o
     io7                     @   sR   d dl Z d dlmZ d dlmZ d dlmZmZmZm	Z	m
Z
 G dd de jZdS )    N)masked_matmul)_csr_ops)_csr_to_coo_dense3d_to_sparse	_diffsort_get_transpose_info_transpose_with_infoc                   @   s  e Zd Zedd Zdd Zdd Zedd Zed	d
 Z	e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edd Zedd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Zed'd( Zed)d* Zed1d-d.Zed/d0 Zd,S )2SparseCSRTensorc                 C   sR   i }|j |d< |j|d< |j|d< |j|d< t|dksJ tjj| |fi |S )Ndevicedtypelayoutrequires_grad   )r
   r   r   r   lentorchTensor_make_wrapper_subclass)clsrow_offsetscolumn_indicesvaluesshapekwargs r   N/home/ubuntu/.local/lib/python3.10/site-packages/xformers/sparse/csr_tensor.py__new__   s   



zSparseCSRTensor.__new__c                 C   s   |j dksJ |j dksJ |j dksJ | | _t||j| _| | _| | _t	| j
d | j
d | j| j| j| _d S )N      )ndim
contiguous_SparseCSRTensor__row_offsetsr   tor   _SparseCSRTensor__row_indices _SparseCSRTensor__column_indices_SparseCSRTensor__valuesr   r   _SparseCSRTensor__transp_info)selfr   r   r   r   r   r   r   __init__   s   



zSparseCSRTensor.__init__c                 C   s   d| j  d| j dS )Nzsparse_csr_tensor(shape=z	, values=))r   r$   r&   r   r   r   __repr__1   s   zSparseCSRTensor.__repr__c                 C   s$   t ||j\}}}}| ||||jS N)r   r
   r   )r   matrixr   row_indicesr   r   r   r   r   
from_dense4   s   zSparseCSRTensor.from_densec                 C   s   dS )z
        assert arg0.is_sparse
        x = arg0.coalesce()
        rows, cols = x.indices().unbind(0)
        vals = x.values()
        _coo_to_csr()
        Nr   )r   arg0r   r   r   from_sparse_coo;   s   	zSparseCSRTensor.from_sparse_cooc                 C   s4   |  | ||||}||_||_||_||_||_|S r+   )r   r$   r"   r    r#   r%   )r   r   r   r-   r   r   _transp_infor,   r   r   r   _wrapF   s   zSparseCSRTensor._wrapc                 C      | j S r+   )r$   r)   r   r   r   r   R   s   zSparseCSRTensor.valuesc                 C   r3   r+   )r"   r)   r   r   r   _csr_row_indicesU      z SparseCSRTensor._csr_row_indicesc                 C   r3   r+   )r    r)   r   r   r   _csr_row_offsetsY   r5   z SparseCSRTensor._csr_row_offsetsc                 C   r3   r+   )r#   r)   r   r   r   _csr_column_indices]   r5   z#SparseCSRTensor._csr_column_indicesc                 C   r3   r+   )r%   r)   r   r   r   _csr_transp_infoa   r5   z SparseCSRTensor._csr_transp_infoc              	   C   s   t || rt|tju stS |jdksJ |jdksJ |}|}|j\}}}|j}|j}	|j	}
|j
}tj|||	|
|||j}|S )Nr   )
isinstancetyper   r   NotImplementedr   r   r"   r$   r    r#   r   _spmmapplyr%   )r   r/   arg1r&   b_mnr-   r   r   r   outr   r   r   _bmme   s   zSparseCSRTensor._bmmc                 C   sj   |dks
|dks
t S |}|j\}}}|j}|j}|j}	|j}
tj|||||	|
}| 	|j|||	|
|j
S )Nr   )r;   r   r"   r$   r    r#   r   _SparseSoftmaxr=   r2   r%   )r   r/   dimr&   r@   rA   rB   r-   r   r   r   rC   r   r   r   _softmax{   s&   zSparseCSRTensor._softmaxc                 C   sx   |dks
|dks
t S |dks|dkst S |j\}}}|j}t||j\}}	}
}t||||
|}| |||f|	||
||S )Nr   r   rE   )r;   r   r$   r   r%   r   r2   )r   r/   dim0dim1BrA   rB   r   output_row_indicesoutput_valuesoutput_row_offsetsoutput_column_indicesnew_transp_infor   r   r   
_transpose   s.   

zSparseCSRTensor._transposec                 C   s   t |tju rt |tju stS |jd |jd ksJ |jd |jd ks(J |j}|j}|j}| }t	j
||dd ||||j}| |j|||||jS )Nr   r   rI   rE   )r:   r   r   r;   r   r"   r    r#   r   r   _sddmmr=   	transposer%   r2   )r   ar?   maskr-   r   r   rC   r   r   r   _masked_matmul   s0   	zSparseCSRTensor._masked_matmulc                    sv   t  tr
t  t  tjsJ | |j|jj d|jj d|j	j d|j
j dt fdd|jD S )Nr
   c                 3   s    | ]	}|j  d V  qdS )rX   N)r!   ).0trX   r   r   	<genexpr>   s    z&SparseCSRTensor._to.<locals>.<genexpr>)r9   strr   r
   r2   r   r$   r!   r"   r    r#   tupler%   )r   r/   r
   r   rX   r   _to   s   

zSparseCSRTensor._toc                 C   s   t || r
t || stS |j|jksJ |j|j}}||| |j|j}}||| |j|j}}||| |j|j}}||| t	|j
|j
D ]\}}||| qW|S r+   )r9   r;   r   r$   
resize_as_copy_r"   r    r#   zipr%   )r   r/   r>   av0av1v0v1r   r   r   _copy   s   zSparseCSRTensor._copyc                 C   sh   t || r
t || stS |j|jkrdS t|j|jsdS t|j|js(dS t|j|js2dS dS )NFT)r9   r;   r   r   equalr$   r    r#   )r   r/   r>   r   r   r   _equal   s   zSparseCSRTensor._equalc                 C   s   |j \}}}|j }tj||j|jd}|j }|j }t||||\}	}tj	t
|j|jdd d d f }
|j||
|	|f< |S )N)r   r
   rX   )r   r   zerosr   r
   r    longr#   r   aranger   r$   )r   r/   r@   rA   rB   r   r,   r   r   row_coob_idxsr   r   r   	_to_dense   s   

"zSparseCSRTensor._to_densec                 C   s  t || ttfrt || ttfstS ||}}t || r|j}t || r'|j}t || rot || rod| d}|jj|jjksCt||jj|jjksOt||jj|jjks[t||j|juret||j|jurot||||}| 	|j||j
|j|j|jS )Nz8arg0 and arg1 need to have the same sparsity pattern in z
 (for now))r9   intfloatr;   r$   r    r   NotImplementedErrorr#   r2   r"   r%   )r   funcr/   r>   rd   re   msgrC   r   r   r   
_binary_op  s>   



zSparseCSRTensor._binary_opc                 C   sB   ||}}t || r| }t || r| }|||}| |S r+   )r9   to_denser.   )r   rr   r/   r>   rd   re   rC   r   r   r   _binary_op_slow(  s   




zSparseCSRTensor._binary_op_slowr   Nc                    s  |d u ri }|t jjt jt jjt jt jjfv r)t|dksJ | |d |d S |t jjt jj	jt jfv r@| 
|d |d S |t jjt jfv r^t|dksQJ | |d |d |d S |tkrwt|dksjJ | |d |d |d S |t jjt jt jjfv rt|dksJ t|d | rt|d | st| dt|d  dt|d  d| ||d |d S |t jjt jt jjfv rt|dksJ | ||d |d S |t jjt jt jjfv rt|dksJ | ||d |d S |t jj	jt jt jfv r+|d }|j }||g|dd  R i |}| |j||j |j!|j"|j#S |t jj$krEt|dks;J | %|d |d S |t jj&fv r`t|dksVJ | '|d |d S |t jj(t j(fv r}t|dkssJ | )|d |d S |t jj*krt|dksJ | +|d S |t jj,kr|d }| |j|j, |j |j!|j"|j#S |t jj-kr|d }|d  | |j|j- |j - |j!- |j"- t. fd	d
|j#D S |t jj/j0t jj1j0fv rt|dksJ t|dksJ |d }| |j|jj/|j |j!|j"|j#S |t jj2kr'||d j t j34 ' ||i |}|t j56 v rE|W  d    S t j78|| W  d    S 1 sWw   Y  t9S )Nr   r   r   rG   r   z with z and z not implementedc                 3   s    | ]}|  V  qd S r+   )__deepcopy__)rY   vmemor   r   r[     s    z5SparseCSRTensor.__torch_function__.<locals>.<genexpr>):r   r   bmm
__matmul__matmulr   rD   softmaxnn
functionalrH   rT   rR   r   rW   add__add__r9   rq   r:   rt   mul__mul__logical_and__and__rv   dropoutdropout_r$   cloner2   r   r"   r    r#   r%   r!   r^   r`   rf   rg   rh   ru   rn   detachrw   r]   grad__get___gradrequires_grad__CDisableTorchFunction	overridesget_default_nowrap_functions_tensor_convertr;   )r   rr   typesargsr   xr   retr   ry   r   __torch_function__3  s   $
		



		"z"SparseCSRTensor.__torch_function__c                 C   s   t S r+   )r;   )r   rr   r   r   r   r   r   r   __torch_dispatch__  s   z"SparseCSRTensor.__torch_dispatch__)r   N)__name__
__module____qualname__staticmethodr   r'   r*   classmethodr.   r0   r2   r   propertyr4   r6   r7   r8   rD   rH   rR   rW   r^   rf   rh   rn   rt   rv   r   r   r   r   r   r   r	      sX    
	
















"

r	   )r   xformers.opsr   xformers.sparser   xformers.sparse.utilsr   r   r   r   r   r   r	   r   r   r   r   <module>   s
   	