o
    )i                     @   s  d dl mZmZ d dlZd dlmZmZmZmZ ddl	m
Z
mZ eG dd de
ZeG dd	 d	e
ZeG d
d de
ZG dd dejjZ		ddejdejdejdeej dedejfddZG dd dejjZdeej deej dejfddZdS )    )OptionalSequenceN)index_select_cat_bwdindex_select_cat_fwdscaled_index_add_bwdscaled_index_add_fwd   )BaseOperatorregister_operatorc                   @      e Zd ZeZdZdZdS )ScaledIndexAddFwindexingZscaled_index_addFN)__name__
__module____qualname__r   OPERATOROPERATOR_CATEGORYNAME r   r   a/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/xformers/ops/indexing.pyr          r   c                   @   r   )ScaledIndexAddBwr   Zscaled_index_addBN)r   r   r   r   r   r   r   r   r   r   r   r      r   r   c                   @   r   )IndexSelectr   Zindex_selectN)r   r   r   r   r   r   r   r   r   r   r   r   $   r   r   c                   @   sV   e Zd Zedejdejdejdeej dedejfddZeej	j
jd	d
 ZdS )_ScaledIndexAddxindexsourcescalingalphareturnc                 C   sL   t d urt ||||| ntd| | | ||| |j| _|| _|S )N:Triton is needed for forward pass but it is not available!)r   RuntimeErrorZ
mark_dirtysave_for_backwardshapesource_shaper   )ctxr   r   r   r   r   r   r   r   forward,   s   

z_ScaledIndexAdd.forwardc                 C   sn   | j \}}}t|}|d u rd n
tj| j|j|jd}td ur,t||||||| j nt	d|d ||d fS )Ndtypedevice;Triton is needed for backward pass but it is not available!)
saved_tensorstorchZ
empty_likeemptyr$   r(   r)   r   r   r!   )r%   grad_outputr   r   r   Zgrad_sourceZgrad_scalingr   r   r   backwardC   s6   

z_ScaledIndexAdd.backwardN)r   r   r   staticmethodr,   Tensorr   floatr&   autogradfunctiononce_differentiabler/   r   r   r   r   r   +   s$    r         ?inputr   r   r   r   r   c                 C   s   t | ||||S )a  
    In-place scaling+index_add

    Indices in ``index`` are assumed to be unique

    The max index in ``index`` is assumed to be less than the size of dim0 of ``input``.

    :Note:

        The FW pass is done in-place (``input`` is modified)

    :Equivalent pytorch code:

    .. code-block:: python

        return torch.index_add(input, dim=0, source=scaling * src, index=indices, alpha=alpha)
    )r   apply)r7   r   r   r   r   r   r   r   scaled_index_addh   s   r9   c                   @   s<   e Zd ZedejdejfddZeejjj	dd Z
dS )_IndexSelectCatargsr   c                 G   s   t |d dks
J |d t |d  }|t |d d  }d}t||D ]\}}|j\}}|jd }	||	| 7 }q%tj|g|d j|d jd}
d}t||D ]0\}}|jd }	|jd }td urvt|
|||	|   |	|g|| nt	d||	| 7 }qP| j
|  dd |D | _|
S )N   r   r'   r   r    c                 S   s   g | ]}|j qS r   )r#   ).0r   r   r   r   
<listcomp>   s    z+_IndexSelectCat.forward.<locals>.<listcomp>)lenzipr#   r,   r-   r(   r)   r   viewr!   r"   source_shapes)r%   r;   sourcesindicesZoutput_numelr   r   num_rowsnum_colsnum_indicesoutputprocessed_numelr   r   r   r&      s>   





z_IndexSelectCat.forwardc                 C   s   | j }g }d}t| j|D ]B\}}|\}}|jd }	||||	|   |	|g}
||	| 7 }tj||g|j|jd}t	d urFt	|||
 nt
d|| qg |d gt| R S )Nr   r'   r*   )r+   r@   rB   r#   Zreshaper,   Zzerosr(   r)   r   r!   appendr?   )r%   r.   rD   Z	gradientsrI   r$   r   rE   rF   rG   Zgrad_output_sliceZgrad_source_slicer   r   r   r/      s8   

z_IndexSelectCat.backwardN)r   r   r   r0   r,   r1   r&   r3   r4   r5   r/   r   r   r   r   r:      s    +r:   rC   rD   c                 C   s   t jg | |R  S )aD  
    Indices in ``index`` are assumed to be unique
    In each (index, source) pair, the max index in ``index`` is assumed to be less than the size of dim0 of ``source``

    :Example:

    Given:
    - ``sources[0]`` of shape ``[S0, D0]``
    - ``indices[0]`` of shape ``[I0]``
    - ``sources[1]`` of shape ``[S1, D1]``
    - ``indices[1]`` of shape ``[I1]``
    returns a ``torch.Tensor`` of shape ``[I0 * D0 + I1 * D1]``

    :Equivalent pytorch code:

    .. code-block:: python

        return torch.cat([s[i.long()].flatten() for s, i in zip(sources, indices)], dim=0)
    )r:   r8   )rC   rD   r   r   r   index_select_cat   s   rK   )Nr6   )typingr   r   r,   Zxformers.ops._tritonr   r   r   r   commonr	   r
   r   r   r   r3   Functionr   r1   r2   r9   r:   rK   r   r   r   r   <module>   sD   A
S