o
    NeE                     @   st  d dl mZ d dlZd dlZd dlZd dlZddlmZm	Z	m
Z
 ddlmZmZmZmZ ddlmZ d dlmZ zd dlmZ W n
   d dlmZ Y ef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 Z dd Z!dd  Z"d!d" Z#d#d$ Z$d%d& Z%d?d'd(Z&d@d*d+Z'd,d- Z(d.d/ Z)d0d1 Z*dAd3d4Z+d5d6 Z,d7d8 Z-d9d: Z.d;d< Z/d=d> Z0dS )B    )print_functionN   )BlockVariable_non_static_mode)convert_dtypecheck_variable_and_dtype
check_typecheck_dtype)LayerHelper)version_info)Sequencec              
   C   s
  t | |r
| g| S zt| }W n ty#   td| d t|  w t||kr<td| d t| d t|  |D ]D}t |trKJ d| z|| W q> ttfy   td| d t| d t| d t|  d	 t| d
 d tt| w |S )an  
    Converts a single numerical type or iterable of numerical
    types into an numerical type list.

    Arguments:
      value: The value to validate and convert. Could an int, or any iterable
        of ints.
      n: The size of the list to be returned.
      name: The name of the argument being validated, e.g. "stride" or
        "filter_size". This is only used to format error messages.
      dtype: the numerical type of the element of the list to be returned.

    Returns:
      A list of n dtypes.

    Raises:
      ValueError: If something else than an int/long or iterable thereof was
        passed.
    zThe z)'s type must be list or tuple. Received: z's length must be z. Received: z7Required numerical type with '%s', but received Tensor.z#'s type must be a list or tuple of  z . Received: z including element z of type)
isinstancelist	TypeError
ValueErrorstrlenr   type)valuennamedtypeZ
value_listZsingle_value r   ID:\Projects\ConvertPro\env\Lib\site-packages\paddle/fluid/layers/utils.pyconvert_to_list   sl   

r   c                 C   s&   t | trdS t | tot | tj S )z7
    Whether `seq` is an entry or nested structure
    T)r   dictr   sixstring_types)seqr   r   r   is_sequenceP   s   
r!   c                  G   s.   t | dksJ tdd | D }t|d@ S )zM
    Return int hash value calculated by id(arg) or tuple(id1,id2, ...).
    r   c                 S      g | ]}t |qS r   )id).0vr   r   r   
<listcomp>^       z!_hash_with_id.<locals>.<listcomp>i)r   tuplehash)argsinfor   r   r   _hash_with_idY   s   r,   c                 C   s(   zt t| W S  ty   tdw )zR
    Returns a sorted list of the dict keys, with error if keys not sortable.
    z,nest only supports dicts with sortable keys.)sortedr   iterkeysr   )Zdict_r   r   r   _sortedb   s
   r/   c                 c   s<    t | trt| D ]}| | V  q
d S | D ]}|V  qd S N)r   r   r/   )iterablekeyr   r   r   r   _yield_valuel   s   
r3   c                 c   s8    t | D ]}t|rt|D ]}|V  qq|V  qd S r0   )r3   r!   _yield_flat_nest)nestr   nir   r   r   r4   z   s   r4   c                 C   s   t | r| S | gS r0   r!   r5   r   r   r   to_sequence   s   r9   c                 C   s   t | r
tt| S | gS )z
	:alias_main: paddle.flatten
	:alias: paddle.flatten,paddle.tensor.flatten,paddle.tensor.manipulation.flatten
	:old_api: paddle.fluid.layers.flatten

    Traverse all entries in the nested structure and put them into an list.
    )r!   r   r4   r8   r   r   r   flatten   s   r:   c                    s   t | trttt| | t|  fddt| D S t | tr>t| dr>t | j	t
r>tdd | j	D r>t| | S t| |S )zE
    Convert the sequence `args` to the same type as `instance`.
    c                 3   s    | ]	}| | fV  qd S r0   r   )r$   r2   resultr   r   	<genexpr>   s    
z!_sequence_like.<locals>.<genexpr>_fieldsc                 s   s    | ]	}t |tjV  qd S r0   )r   r   r   )r$   fr   r   r   r=      s    )r   r   zipr/   r   r   r.   r(   hasattrr>   r   all)instancer*   r   r;   r   _sequence_like   s   

rD   c                 C   s^   g }t | D ]$}t|rt|||\}}|t|| |}q|||  |d7 }q||fS )z/
    Helper function for pack_sequence_as.
       )r3   r!   _packed_nest_with_indicesappendrD   )	structureflatindexpackedsZ	new_indexchildr   r   r   rF      s   
rF   c                 C   s   t |stdt | st|dkrtdt| |d S t| }t|t|kr8tdt|t|| |f t| |d\}}t| |S )zA
    Pack a given flattened sequence into a given structure.
    z flat_sequence must be a sequencerE   z6Structure is a scalar but len(flat_sequence) == %d > 1r   zyCould not pack sequence. Structure had %d elements, but flat_sequence had %d elements.  Structure: %s, flat_sequence: %s.)r!   r   r   r   r:   rF   rD   )rH   Zflat_sequenceflat_structure_rK   r   r   r   pack_sequence_as   s&   
rP   c                    s2   dd |D }t | }t|d  fdd|D S )zO
    Apply `func` to each entry in `structure` and return a new structure.
    c                 S   r"   r   )r:   )r$   rL   r   r   r   r&      r'   z!map_structure.<locals>.<listcomp>r   c                    s   g | ]} | qS r   r   )r$   xfuncr   r   r&      r'   )r@   rP   )rS   rH   rN   entriesr   rR   r   map_structure   s   rU   c                 C   s   | D ]	}t |r dS qdS )zD
    Returns whether structure holds sequence like `list/dict`.
    TFr7   )rH   rL   r   r   r   hold_mutable_vars   s
   rV   c                 C   s   t  t| }t| |S )zE
    Returns vars copied from sequence without mutable property.
    )copyr:   rP   )rH   rN   r   r   r   copy_mutable_vars   s   
rX   c                 C   s   t | }|t |krtd| |f |sdS |rKt| }t|}||kr,td||f t| trKtt| }tt|}||krKtd	||dd t
| D }dd t
|D }	t||	D ]
\}
}t|
|| qbdS )z6
    Helper function for `assert_same_structure`.
    zdThe two structures don't have the same nested structure.

First structure: %s

Second structure: %s.NzvThe two structures don't have the same sequence type. First structure has type %s, while second structure has type %s.zvThe two dictionaries don't have the same set of keys. First structure has keys {}, while second structure has keys {}.c                 S      g | ]}|qS r   r   r$   r   r   r   r   r&         z4_recursive_assert_same_structure.<locals>.<listcomp>c                 S   rY   r   r   rZ   r   r   r   r&     r[   )r!   r   r   r   r   r   setr   r.   formatr3   r@    _recursive_assert_same_structure)nest1nest2check_typesZis_sequence_nest1Z
type_nest1Z
type_nest2Zkeys1keys2Znest1_as_sequenceZnest2_as_sequenceZn1Zn2r   r   r   r^      s>   
r^   c                 C   s$   dd }|| |} |||}| |fS )Nc                    s@   fdd t | rt|  fddt| D } | S  | } | S )Nc                    s   | d u r S | S r0   r   rQ   )objr   r   change_none_to_obj  s   z`padding_to_same_structure.<locals>._padding_to_same_structure_single.<locals>.change_none_to_objc                    s   g | ]} |qS r   r   )r$   item)re   r   r   r&     r'   zXpadding_to_same_structure.<locals>._padding_to_same_structure_single.<locals>.<listcomp>)r!   rP   r:   )r   rd   r   )re   rd   r   !_padding_to_same_structure_single  s   zDpadding_to_same_structure.<locals>._padding_to_same_structure_singler   )r_   r`   rd   rg   r   r   r   padding_to_same_structure  s   

rh   Tc                 C   s\   t | r
tt| nd}t |rtt|nd}||kr&td|| ||f t| || dS )z@
    Confirm two nested structures with the same structure.
    rE   zThe two structures don't have the same number of elements.

First structure (%i elements): %s

Second structure (%i elements): %sN)r!   r   r:   r   r^   )r_   r`   ra   Z	len_nest1Z	len_nest2r   r   r   assert_same_structure%  s   
ri   c                 C   sf   t | |d kst | |ksJ d}t | |d kr1t|D ]}| |d  | |d d  kr0d}q|S )z/
    Check whether padding is symmetrical.
    r   TrE   F)r   range)paddingZdata_dimZis_sysir   r   r   _is_symmetric_padding3  s    rm   c                 C   s   | D ]
}t |tr dS qdS )z8
    Check whether list or tuple contains variable.
    TF)r   r   )Zlist_or_tuplerf   r   r   r   _contain_var@  s
   
rn   c                    s   ddl mm  dd } fdd}t|tr=d|_t|jdd	d
gdd d  t|jd
kr7 |d	}|| d< d S t|t	t
frjt|dksVJ d dt|  |||d< t|rh||| d< d S d S td)NrE   )fill_constantcastc                 S   s:   g }t | D ]\}}t|tr|d q|| q|S )N)	enumerater   r   rG   )
list_shapeZ
attr_shapeidxdimr   r   r   _get_attr_shapeM  s   
z0get_shape_tensor_inputs.<locals>._get_attr_shapec                    s   g }t | D ]B\}}t|tr:d|_t|jdt| d ddgd d  t|jdkr4 |dd}|| qd	gd|dd
}|| q|S )NTzshape[]int32int64(When type of shape inzis list or tuple.))rQ   r   rE   Z	force_cpu)	rr   r   r   stop_gradientr
   r   r   r   rG   )rs   Zshape_tensor_listrt   ru   temp_outrp   ro   op_typer   r   _get_shape_tensorV  s   

z2get_shape_tensor_inputs.<locals>._get_shape_tensorTshaperx   ry   ro   rz   z is Variable.)ZShapeTensorr   zThe size of 'shape' inz  can't be zero, but received %s.ZShapeTensorListz0Shape only supports Variable, or list, or tuple.)tensorro   rp   r   r   r|   r
   r   r   r   r(   r   rn   r   )Zinputsattrsr   r   rv   r   r   r~   r   get_shape_tensor_inputsJ  s,   	


r   rx   c                 C   sf   ddl m} g }| D ]&}t|trd|_|| q
t|tjs"J |dg||dd}|| q
|S )z6
    Converts all elements of a list to Variable.
    rE   )ro   Tr{   )r   ro   r   r   r|   rG   r   integer_types)Zold_listr   ro   Znew_list_tensoreler}   r   r   r   _convert_to_tensor_listy  s   
r   c                 C   s:   t | ttfrttdd | } | S |  t } | S )zI
    Convert shape(list, tuple, variable) to list in imperative mode
    c                 S   s   t | tr|  jd S | S )Nr   )r   r   numpyrI   rc   r   r   r   <lambda>  s   z'convert_shape_to_list.<locals>.<lambda>)r   r   r(   mapr   Zastypeinttolist)r   r   r   r   convert_shape_to_list  s   r   c                 C   s^   t | trt| jdddgd dS | D ]}t |ts,|dk r"tdt |tjs,tdqdS )	zU
    Check shape type and shape elements type before passing it to fill_constant
    r   rx   ry   ro   r   zDAll elements in ``shape`` must be positive when it's a list or tuplezDAll elements in ``shape`` must be integers when it's a list or tupleN)r   r   r
   r   r   r   r   r   )r   r   r   r   r   check_shape  s   

r   c                 C   sF   t  sd| jv rt|trt|}|r!| j| dS dS dS dS dS )a[  Try to set static shape of tensor from a shape tensor.
    
    For example,

    import paddle
    paddle.enable_static()
    data = paddle.static.data(name="x", shape=[-1, 2], dtype='float32')
    shape = paddle.shape(data)  # shape should be [-1, 2] instead of [-1, -1]
    x = paddle.uniform(shape) 
    print(x.shape) 
    # (-1, 2)
    
    rq   N)r   r   r   r   "try_get_constant_shape_from_tensordesc	set_shape)r   r   r   r   r   try_set_static_shape_tensor  s   

r   c                 C   sX   t  s*z | jdur| j}|jdkr!| jj|jd  }|jW S W dS W dS    Y dS dS )aX  Try to get shape from a tensor with constant value.

    For example,
    
    import paddle
    paddle.enable_static()
    data = paddle.static.data(name="x", shape=[-1, 2], dtype='float32')
    shape = paddle.shape(data)  # shape should be [-1, 2] instead of [-1, -1]
    x = paddle.uniform(shape) 
    print(x.shape) 
    # (-1, 2)
    
    Nr   r   )r   opr   blockvarsZinput_arg_namesr   )Zshape_tensorZgenerate_opvarr   r   r   r     s    

	r   c                 C   s   t | ts	J d| jdksJ dt }t }| jD ]2}|jD ]}||D ]}| |s3|| q'q |j	D ]}|
|D ]}| |sK|| q?q8q||fS )zg
    Returns the inputs and outputs variable used in this block but not
    created in this block.
    z9input non-Block argument for get_inputs_outputs_in_block.rq   z2input block should be a sub-block, not main block.)r   r   Z
parent_idxr\   opsZinput_namesinputZhas_varaddZoutput_namesoutput)r   Zinner_inputsZinner_outputsr   ZinameZin_var_nameZonameZout_var_namer   r   r   get_inputs_outputs_in_block  s0   






r   r0   )T)rx   )1
__future__r   collectionsrW   r   r   npZ	frameworkr   r   r   Zdata_feederr   r   r	   r
   Zlayer_helperr   sysr   collections.abcr   r   r   r!   r,   r/   r3   r4   r9   r:   rD   rF   rP   rU   rV   rX   r^   rh   ri   rm   rn   r   r   r   r   r   r   r   r   r   r   r   <module>   sN   2		
		

!


/