o
    X۷i                     @  s   d dl mZ zd dlZdZW n ey   dZY nw d dlZd dlmZ d dlm	Z	 d dlm
Z
 d dlmZ G d	d
 d
e
jZdd ZdS )    )annotationsNTF)_core)_csc)_data)_utilc                   @  sl   e Zd ZdZdZdddZddd	Zdd
dZdd ZdddZ	dddZ
dddZdddZdddZdS )
dia_matrixa  Sparse matrix with DIAgonal storage.

    Now it has only one initializer format below:

    ``dia_matrix((data, offsets))``

    Args:
        arg1: Arguments for the initializer.
        shape (tuple): Shape of a matrix. Its length must be two.
        dtype: Data type. It must be an argument of :class:`numpy.dtype`.
        copy (bool): If ``True``, copies of given arrays are always used.

    .. seealso::
       :class:`scipy.sparse.dia_matrix`

    diaNFc           	      C  sP  t rtj|r| }|j}|j}|j}|j}d}nt	|t
r-|\}}|d u r,tdntdtj|||d}t|}tj|d|d}t|}|jdkrTtd|jdkr]td	|jd
 t|krstd|jd
 t|f t|}|d d |dd  k rtd|| _|| _t|stdt|d
 t|d f| _d S )NFzexpected a shape argumentz,unrecognized form for dia_matrix constructor)dtypecopyi   zoffsets array must have rank 1   zdata array must have rank 2r   zBnumber of diagonals (%d) does not match the number of offsets (%d)z&offset array contains duplicate valuesz(invalid shape (must be a 2-tuple of int))_scipy_availablescipysparseissparsetodiadataoffsetsshaper	   
isinstancetuple
ValueErrorcupyarray
atleast_2d
atleast_1dndimlensortanyr   isshapeint_shape)	selfarg1r   r	   r
   xr   r   sorted_offsets r)   M/home/ubuntu/vllm_env/lib/python3.10/site-packages/cupyx/scipy/sparse/_dia.py__init__'   sJ   






zdia_matrix.__init__Tc                 C  s0   |rt || j f| jdS t || jf| jdS )zReturns a matrix with the same sparsity structure as self,
        but with different data.  By default the structure arrays are copied.
        r   )r   r   r
   r   )r%   r   r
   r)   r)   r*   
_with_dataS   s   zdia_matrix._with_datac                 C  s:   t std| j|}| j|}tjj||f| jdS )a:  Returns a copy of the array on host memory.

        Args:
            stream (cupy.cuda.Stream): CUDA stream object. If it is given, the
                copy runs asynchronously. Otherwise, the copy is synchronous.

        Returns:
            scipy.sparse.dia_matrix: Copy of the array on host memory.

        zscipy is not availabler,   )	r   RuntimeErrorr   getr   r   r   r   r$   )r%   streamr   r   r)   r)   r*   r/   \   s
   zdia_matrix.getc                 C  s   | j S )zcReturns the shape of the matrix.

        Returns:
            tuple: Shape of the matrix.
        )r$   )r%   r)   r)   r*   	get_shapem   s   zdia_matrix.get_shapec              	   C  sB   |durt d| j\}}tddddddd	| j||}t|S )
zReturns the number of stored values, including explicit zeros.

        Args:
            axis: Not supported yet.

        Returns:
            int: The number of stored values.

        Nz5getnnz over an axis is not implemented for DIA formatzint32 offsets, int32 m, int32 nz	int32 nnzz7offsets > 0 ? min(m, n - offsets) : min(m + offsets, n)za + bznnz = a0dia_nnz)NotImplementedErrorr   r   ReductionKernelr   r#   )r%   axismnnnzr)   r)   r*   getnnzu   s   

zdia_matrix.getnnzc                 C  s   |   j||dS )z3Returns a dense matrix representing the same value.)orderout)tocsctoarray)r%   r;   r<   r)   r)   r*   r>      s   zdia_matrix.toarrayc                 C  s   | j jdkrtj| j| jdS | j\}}| j j\}}tdddd|| jdddf ||| j \}}t	j
|d d	d}t	|jdd
|d|d < || ||d d< |j|j jd	dd}	| j j|j }
tj|
|	|f| j| jdS )a{  Converts the matrix to Compressed Sparse Column format.

        Args:
            copy (bool): If ``False``, it shares data arrays as much as
                possible. Actually this option is ignored because all
                arrays in a matrix cannot be shared in dia to csc conversion.

        Returns:
            cupyx.scipy.sparse.csc_matrix: Converted matrix.

        r   r	   zGint32 offset_len, int32 offsets, int32 num_rows, int32 num_cols, T datazint32 row, bool maskz
            int offset_inds = i % offset_len;
            row = offset_inds - offsets;
            mask = (row >= 0 && row < num_rows && offset_inds < num_cols
                    && data != T(0));
            cupyx_scipy_sparse_dia_tocscNr   r   )r6   F)r
   )r   r	   )r   sizer   
csc_matrixr   r	   r   ElementwiseKernelr   r   zeroscumsumsumTastype)r%   r
   num_rowsnum_colsnum_offsets
offset_lenrowmaskindptrindicesr   r)   r)   r*   r=      s*   

zdia_matrix.tocscc                 C  s   |    S )ax  Converts the matrix to Compressed Sparse Row format.

        Args:
            copy (bool): If ``False``, it shares data arrays as much as
                possible. Actually this option is ignored because all
                arrays in a matrix cannot be shared in dia to csr conversion.

        Returns:
            cupyx.scipy.sparse.csc_matrix: Converted matrix.

        )r=   tocsr)r%   r
   r)   r)   r*   rQ      s   zdia_matrix.tocsrr   c                 C  s   | j \}}|| ks||krtjd| jjdS t| j|k\}td|t|| |}}|j	dkr=tj
|| | jjdS | j|d ||f S )a  Returns the k-th diagonal of the matrix.

        Args:
            k (int, optional): Which diagonal to get, corresponding to elements
            a[i, i+k]. Default: 0 (the main diagonal).

        Returns:
            cupy.ndarray : The k-th diagonal.
        r   r?   )r   r   emptyr   r	   nonzeror   maxminrA   rD   )r%   krowscolsidx	first_collast_colr)   r)   r*   diagonal   s   


zdia_matrix.diagonal)NNF)T)N)NN)F)r   )__name__
__module____qualname____doc__formatr+   r-   r/   r1   r:   r>   r=   rQ   r\   r)   r)   r)   r*   r      s    

,
	



&r   c                 C  s
   t | tS )zChecks if a given matrix is of DIA format.

    Returns:
        bool: Returns if ``x`` is :class:`cupyx.scipy.sparse.dia_matrix`.

    )r   r   )r'   r)   r)   r*   isspmatrix_dia   s   
rb   )
__future__r   scipy.sparser   r   ImportErrorr   r   cupyx.scipy.sparser   r   r   _data_matrixr   rb   r)   r)   r)   r*   <module>   s     E