o
    Ne=r                     @   s   d dl Z d dlZddlmZ ddlmZ d dlZdZdd Zdd	 Z	d
d Z
G 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d Zdd Zd d! Zd"d# ZdS )$    N   )unique_namecoreic                    s<    fdd t | ttfsdS | D ]	} |s dS qdS )Nc                    sH   t | ttfst| ksdS t | ttfr"| D ]	} |s! dS qdS NFT)
isinstancelisttupletype)items_is_list_tuplecontain_type KD:\Projects\ConvertPro\env\Lib\site-packages\paddle/fluid/variable_index.pyr      s   z%is_list_tuple.<locals>._is_list_tupleFT)r   r	   r   )indexr   r   r   r   r   is_list_tuple   s   	r   c                 C   s,   t | tr| D ]
}t ||s dS qdS dS r   )r   r   )r   r   ir   r   r   is_one_dim_list+   s   

r   c                 C   sf   t | }t |}||d  | d }dg| }|dd  |d |d < | |d d  ||d d < |S )Nr   r   )len)Zvar_dimsZ
index_dimsZvar_dims_sizeZindex_dims_sizeZout_dims_sizeZout_dims_shaper   r   r   get_list_index_shape5   s   
r   c                   @   sD   e 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 )	SliceInfoc                 C   s   d | _ g | _d | _d S N)	pre_shapeindexesdtype)selfr   r   r   __init__E   s   
zSliceInfo.__init__c                 C   s   t |tst|tjjtjfrst|tjjst|}| j	d u r%|j	| _	n|j	| j	kr5t
d|j	| j	| j| | jd u rF|j| _d S | j|jkrjt| j|j}tt| jD ]}t| j| || j|< q[| jd j| _d S td|)NzmData type of Tensor/List index should be same. The current data type is {}, but the previous data type is {}.z=Index should be list/tuple of int or Tensor, but received {}.)r   intr   paddlefluidVariablenpndarrayassignr   
IndexErrorformatr   appendr   shapeZbroadcast_shaperanger   broadcast_to
ValueError)r   r   Z	cur_shaper   r   r   r   updateJ   s8   




zSliceInfo.updatec                 C   sH   dgt | }tt |d ddD ]}||d  ||d   ||< q|S )Nr      r   )r   r+   )r   r*   r   r   r   r   r   shape_stridek   s   zSliceInfo.shape_stridec                 C   s   t dd |S )Nc                 S   s   | | S r   r   )xyr   r   r   <lambda>s       z!SliceInfo.numel.<locals>.<lambda>)reduce)r   r*   r   r   r   numelr   s   zSliceInfo.numelc                 C   s   | j D ]}t|tjjstdt|qt| j t|ks&t| j dkr<t	| j }t
tdt| jd dg }ntdt|| jd t||}|S )Nz0only support list/tensor index, but received {}.r   r   zJtoo many indices for tensor: tensor is {}-dimensional, but {} were indexed)r   r   r!   r"   r#   r-   r(   r
   r   stackr   r+   r   Z	transpose)r   Ztensor_shaper   r*   axesshape_transposer   r   r   get_offset_strideu   s,   
 zSliceInfo.get_offset_stridec                 C   s"   |  |j}t|}t||S r   )r:   r*   r!   r&   	gather_nd)r   tensorr9   r   r   r   r   get_item   s   
zSliceInfo.get_itemc                 C   s  t |tjjst|}d }|jtjjj	tjjj
fv r|}n|j}|tjjj	}|j|jkr5||j}| |j}t|}t|jt| jgt| jd j }dgt| }t|j|t|j d < tt|D ]}	||	 ||	 ks||	 dkstd|j|qlt||}
|
dg|t|jd d   }|d|jd g}t| |jd |jd  }g }t|jd D ]}	||	 |  }|| qt|dg}|dgt|j|jd d   }t|||}|d ur||}||j|d d < |S )Nr   r   z{} can not broadcast into {}r   )r   r!   r"   r#   r&   r   r   VarDescVarTypeFP32FP64astyper:   r*   r   r   r   r   r+   r-   r(   r,   Zreshaper0   sumr)   r7   Zscatter)r   Ztensor_originvalueZtensor_typer<   r9   r   Zgather_tensor_shapeZvalue_dims_bdr   Zvalue_broadcastZvalue_1dZindex_1dZtensor_strideZindstempZ	t_reshapeoutr   r   r   set_item   sb   

$
zSliceInfo.set_itemN)
__name__
__module____qualname__r   r.   r0   r6   r:   r=   rG   r   r   r   r   r   C   s    !r   c                    s   ddl m  t|} fdd|D }|t}|dkr|S |dkr&td|t}|t|d kr9|d d S td gt| j	t| |d  d  |||d < |S )Nr   r#   c                    s(   g | ]}t | tjfs|d ur|qS r   )r   r$   r%   ).0elerK   r   r   
<listcomp>   s    z$replace_ellipsis.<locals>.<listcomp>r   z0An index can only have a single ellipsis ('...')r   )
	frameworkr#   r   countEllipsisr'   r   r   slicer*   )varr   Zitem_remove_varZ	ell_countZell_idxr   rK   r   replace_ellipsis   s(   


rT   c                 C   s:   g }| D ]}t |tjr|t| q|| q|S r   )r   r$   r%   r)   r!   r&   )r   new_item
slice_itemr   r   r   replace_ndarray   s   rW   c                 C   s@   g }g }t | D ]\}}|d u r|| q|| q||fS r   )	enumerater)   )r   rU   	none_axesr   rV   r   r   r   replace_none   s   rZ   c                 C   sH   ddl m} t| trdS t| |r"t| jdkr"| jd dkr"dS dS )Nr   rK   Tr   F)rO   r#   r   r    r   r*   rM   r#   r   r   r   is_integer_or_scalar_tensor  s   

r\   c                 C   s*   ddl m} t| |r| jtjkrdS dS )Nr   rK   TF)rO   r#   r   r   r!   boolr[   r   r   r   is_bool_tensor  s   r^   c           
      C   s   ddl m} ddlm} ||r=|j|dd||< t|D ]\}}	t|	|r3| | d d||< q| | |	 qd S || |< d S )Nr   rK   utilsint64r   r   )	rO   r#   layersr`   _contain_var_convert_to_tensor_listrX   r   r)   )
attrsattrZ	attr_nameZtensor_attr_nameinputsinfer_flagsr#   r`   r   dimr   r   r   
deal_attrs  s   



rk   c                    s   t jt jkrtdt jt jtjD ]\}}|j| kr4td|j| |qdd dd  ddlm} | fd	d
 fdd
S )NThe dims of bool index doesn't match indexed array, the dims of bool index except to be equal or less than {}, but received {}.xThe dimension of bool index doesn't match indexed array along dimension {}, the target dimension is {}, but received {}.c                 S   s.   ddl m} ddlm} ||dk}|| |S )Nr   wherer/   )r;   T)	layers.nnro   r<   r;   )rS   r   ro   r;   Z
bool_2_idxr   r   r   idx_not_empty1  s   
z0get_value_for_bool_tensor.<locals>.idx_not_emptyc                 S   s"   t | j}d|d< tj|| jdS )Nr   rb   )r   r*   r!   emptyr   )rS   Z	var_shaper   r   r   	idx_empty8  s   
z,get_value_for_bool_tensor.<locals>.idx_emptyr   condc                      s
    S r   r   r   )rq   r   rS   r   r   r3   >  s   
 z+get_value_for_bool_tensor.<locals>.<lambda>c                      s    S r   r   r   )rs   rS   r   r   r3   ?  r4   r   r*   r'   r(   rX   Zlayers.control_flowru   any)rS   r   r   dim_lenru   r   )rs   rq   r   rS   r   get_value_for_bool_tensor$  s&   ry   c           %   	      sJ  ddl m}m} t|trt|tst|}t|ts|f}g }g }g }g }g }g }	d}
t|}t	| |}t
|\}}t }t|D ]\}}t|rt|st|trv| j| durv| j| dkrv|| j| krvtd|||| j| f || |}d}|dkr|d nt}net|tr|j}|j}|j}|du r|du r|du rqB|du rdn|}|du r|dkrdnt}|du r| j| dkrtjj  s| j tjjjkr|dkr| j| nd}n|dkrtnd}nt|trd}t |tr|!| qB|D ]}t|tu rd}qt|t"st#d	qt$|dkr*td
%t$|g }|r]t$|| jd krFtd%| jd t$|t|D ]\}}|du rX|| qJ|}n+t|D ]$\}}t|tu rs|| qa|du r|d qa|d qa|}ddl&m'} ddl(m)} |t*+|,d}|| |dd  S t||tj-j.frt$|dkrddl(m)} |j/tj"krt0| |  S t$|jdkr|| |dd  S |!| qB|!| qBtd%||| || || || |dkrdn|
}
qB|j1r(t$|j1t$|kr#td%||2| S d| gi}|g g |d}|
r;g |d< dgt$| }t3||dd|| t3||dd|| t3||dd|| ||d< | }t$|dkr|
rodnd}tjj 4 r|dkrd|5 v r|d }n|d }d|5 v r|d }n|d }tj6| ||||d |d }n#| 7 }|j8t9:| j;d | | j/d} |j<||d | gi|d! | }t$|	dkrdd"l=m>}! |!||	d#}t$|t$| jkr|dd }t$|dkr#t|D ]\} t$ fd$d%|D }" |" }#|#||< qdd&l(m?}$ |$||d#}|S )'zy
    Slice the variable.

    Args:
        item(int/slice/tuple) : the index.

    Returns:
        Sliced variable
    r   default_main_programr#   FNr   z>slice_item %d at dim %d should be >= 0 and < var.shape[%d]: %dr   Tz'Only support int or bool in index list.zBWhen index contains a list, its length must be 1, but received {}.zwThe dimension of bool index doesn't match indexed array along dimension 0, the target dimension is {}, but received {}.r&   r/   )index_selectZint32)r   axisEValid index accept int or slice or ellipsis or list, but received {}.Input)r8   startsendsdecrease_axisstridesr   StartsTensorListr   EndsTensorListZStridesTensorListri   Zstrided_slicerR   r   _)namer   Out)r
   rh   outputsrf   )reverser~   c                    s   g | ]}| k r|qS r   r   )rL   r   r   r   r   rN     s    z"_getitem_impl_.<locals>.<listcomp>)	unsqueeze)@rO   r{   r#   r   r   r   r    r	   rW   rT   rZ   r   rX   r\   r^   r*   r'   r)   MAX_INTEGERrR   startstopstepr!   r"   _non_static_modedescr
   r   r>   r?   LOD_TENSOR_ARRAYr   r.   r]   	TypeErrorr   r(   rc   r&   r<   r}   r$   arrayrB   eagerTensorr   ry   r   r=   rk   Zin_dygraph_modekeysZ_C_opscurrent_blockZ
create_varr   Zgenerate_with_ignorable_keyr   	append_opZlayers.tensorr   r   )%rS   r   r{   r#   decrease_axesr8   r   r   stepsZreverse_axesZuse_strided_slicerY   
slice_inforj   rV   r   r   endZall_boolr   Znew_slice_itemidxrM   r&   r}   rh   rf   ri   rF   Zop_typestZtarget_blockZslice_out_varr   lZnew_axisr   r   r   r   _getitem_impl_B  sh  
























	r   c           
      C   s   ddl m}m}m} ddl m} | rJ dt||tfrFddlm} ddl	m
} dd	lm}	 t	j
||d
d}||}|	||| d dS tdt|)a   branches for tensor array setitem operation.
        A item can be a:
        (1) int/Variable, which is a simple number/variable such as [1], [-2]
        (2) Slice, which is represented by bounds such as [2:-1]
        (3) Tuple, which includes the above two cases such as [2:-1, 1]
        If item is case (1), we perform paddle.tensor.array_write, 
        in other cases, we raise a NotImplementedError.
    r/   )LayerHelperr   r   r   rK   z=setitem for tensor_array must be called in static graph mode.r   )to_static_variable)cast)array_writera   rb   )r1   r   r   zEOnly support __setitem__ by Int/Variable in tensor_array, but gets {}N)rO   r   r   r   r#   r   r    Z:paddle.fluid.dygraph.dygraph_to_static.variable_trans_funcr   r!   r   Zpaddle.tensorr   NotImplementedErrorr(   r
   )
rS   r   rD   r   r   r   r#   r   r   r   r   r   r   _setitem_for_tensor_array*  s    	
r   c                 C   s`  ddl m}m} ddlm} | j|jjjkrt	| ||S d| i}t
|tr.t|ts.t|}t
|ts6|f}g }g }g }	g }
g }t|}t| |}t|\}}t }d}t|D ]\}}t|ryt|sy|| |}|dkrt|d nt}d}nt
|tr|j}|j}|j}|d u r|d u r|d u r|d7 }qX|d u rdn|}t
||s|dkrtd|t
||r|d u s|d u rtd|d u r|dkrdnt}|d u r|dkrtndt }nzt
|tr"t|tr|| qX|D ]}t
|t st!d	t|qt"|dkrt#d
t"|ddl$m%} ||}t&| ||  S t
||rO|j'|jjj(krIt"|dkrAt#dt"|t&| ||  S || qXt#d||| |	| |
| || |d7 }qX|j)rt"|j)t"|krt#d||*| |S ||	|
|||d}ddl$m+} |,|	r|-|	|d< |d= |,|
r|-|
|d< |d= |,|r|-||d< |d= | j'}||d< ddl.m/} t
|tt0frt12|g3||}t
|t1j4rxt|j5}||jjj(krd}dd |j6D }ng||jjj7krd}dd |j6D }nT||jjj8kr.d}dd |j6D }nA||jjj9krAd }d!d |j6D }n.||jjj:krTd"}d#d |j6D }n||jjj;krgd$}d%d |j6D }nt!d&|| |||< ||d'< nt
|||j<j=fr||d(< n	t!d)t|t>j?j @ r| A  | B }|jCd*|d+| i|dd+id, | S )-Nr   rz   r   r   r   r   zSWhen assign a value to a paddle.Tensor, step can not be 0, but received step is {}.zWhen assign a value to a paddle.Tensor, it's not supported that the start or end is None when the type of step is paddle.Tensor.z!Doesn't support {} in index list.zGWhen index contains a bool list, its length must be 1, but received {}.r|   zIWhen index contains a bool tensor, its length must be 1, but received {}.zWValid index accept int, slice, ellipsis, None, list of bool, Variable, but received {}.r   )r8   r   r   r   r   rY   r_   r   r   r   r   ZStepsTensorListr   r   )convert_dtypeZbool_valuesc                 S      g | ]}t |qS r   r    rL   vr   r   r   rN         z"_setitem_impl_.<locals>.<listcomp>Zfp32_valuesc                 S   r   r   floatr   r   r   r   rN     r   Zfp64_valuesc                 S   r   r   r   r   r   r   r   rN     r   Zint32_valuesc                 S   r   r   r   r   r   r   r   rN     r   Zint64_valuesc                 S   r   r   r   r   r   r   r   rN     r   Zfp16_valuesc                 S   r   r   r   r   r   r   r   rN     r   zWhen assign a numpy.ndarray, integer or float to a paddle.Tensor, the data type of the paddle.Tensor must be bool, float32, int32, int64 or float16, but received %s.r*   ZValueTensorzlOnly support to assign an integer, float, numpy.ndarray or paddle.Tensor to a paddle.Tensor, but received {}	set_valuer   )r
   rh   r   rf   Zinplace_map)DrO   r{   r#   Zpaddle.fluidr   r
   r>   r?   r   r   r   r   r   r    r	   rW   rT   rZ   r   rX   r\   r^   r)   r   rR   r   r   r   r-   r(   r   r.   r]   r   r   r'   rc   r&   set_value_for_bool_tensorr   BOOLr   rG   r`   rd   re   Zdata_feederr   r   r$   r   rB   r%   r*   Zflatr@   rA   ZINT32ZINT64ZFP16r   r   r!   r"   r   Z_bump_inplace_versionr   r   )rS   r   rD   r{   r#   r   rh   r   r8   r   r   r   rY   r   rj   r   rV   r   r   r   r   r&   Z
idx_tensorrf   r`   r   r   r*   Z
value_namevaluesZ	cur_blockr   r   r   _setitem_impl_D  sF  
















	



r   c                    s   t jt jkrtdt jt jtjD ]\}}|j| kr4td|j| |qdd  ddlm} |  fdd S )	Nrl   rm   c                 S   s   ddl m} ddlm} ddlm} ddlm}m} t	||s'||
| j}||}|| |}	||	 }
|| ||
}|| d d < d S )Nr   rK   r|   rn   r/   )r;   scatter_nd_add)rO   r#   rc   r&   rp   ro   r<   r;   r   r   r   r   )rS   r   rD   r#   r&   ro   r;   r   r   Z
gather_valZgather_val_newrF   r   r   r   rq     s   

z0set_value_for_bool_tensor.<locals>.idx_not_emptyr   rt   c                      s    S r   r   r   rq   r   rD   rS   r   r   r3     s    z+set_value_for_bool_tensor.<locals>.<lambda>rv   )rS   r   rD   r   rx   ru   r   r   r   r     s"   r   )sysnumpyr$    r   r   r!   r   r   r   r   r   rT   rW   rZ   r\   r^   rk   ry   r   r   r   r   r   r   r   r   <module>   s0   
 "

 i ;