o
    X۷i                    @  s  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 d dl
mZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d dlZG d
d dZdd Zdd Zdd Zi ddddddddddddddddddddd d!dfd"d#d d!dfd$dd%dd&d'd(d'd)d'd*d'd'ddd+d+d'd'd'd,d'd-d-d.d/d0Z i dd1dej!dfdd1dd1dd1dd1dd1dd1dd1dd2d"d2d$d1d%d1d&d1d(d1d)d1d*d1d1d1d1ej!dfej!dfd1d1d1d1d1d2d2ej!dfd3d0Z"d4d5 Z#e$ d6d7 Z%dd:d;Z&dd>dZ'dd?d@Z(ddBdZ)ddCdZ*ddFdZ+ddGdZ,ddHdZ-ddIdZ.ddJdZ/ddKd$Z0ddLd%Z1dMd& Z2dNd( Z3ddPd)Z4dQd* Z5dRdS Z6dTdU Z7dVdW Z8dXdY Z9dZd[ Z:d\d] Z;d^d_ Z<d`da Z=dbdc Z>ddde Z?dfdg Z@G dhdi diZAG djdk dkeAZBG dldm dmeAZCG dndo doeAZDG dpdq dqeAZEddrdZFddsd"ZG	=	=ddtduZHddvdwZIddydzZJdd{d|ZKdd}d~ZLdddZMdS )    )annotationsN)driver)runtime)cusparse)_dtype)device)stream)_utilc                   @  sV   e Zd Zdd Zedd Zdd ZejfddZ	d	d
 Z
dd Zdd Zdd ZdS )MatDescriptorc                 C  s
   || _ d S N)
descriptor)selfr    r   D/home/ubuntu/vllm_env/lib/python3.10/site-packages/cupyx/cusparse.py__init__      
zMatDescriptor.__init__c                 C  s   t  }t|S r   )	_cusparsecreateMatDescrr
   )clsdescrr   r   r   create   s   zMatDescriptor.createc                 C  s
   | j dfS )Nr   )r   )r   r   r   r   
__reduce__   r   zMatDescriptor.__reduce__c                 C  s*   | rd S | j rt| j  d | _ d S d S r   )r   r   destroyMatDescrr   is_shutting_downr   r   r   __del__    s   
zMatDescriptor.__del__c                 C     t | j| d S r   )r   
setMatTyper   )r   typr   r   r   set_mat_type'      zMatDescriptor.set_mat_typec                 C  r   r   )r   setMatIndexBaser   )r   baser   r   r   set_mat_index_base*   r    z MatDescriptor.set_mat_index_basec                 C  r   r   )r   setMatFillModer   )r   	fill_moder   r   r   set_mat_fill_mode-   r    zMatDescriptor.set_mat_fill_modec                 C  r   r   )r   setMatDiagTyper   )r   	diag_typer   r   r   set_mat_diag_type0   r    zMatDescriptor.set_mat_diag_typeN)__name__
__module____qualname__r   classmethodr   r   r	   r   r   r   r#   r&   r)   r   r   r   r   r
      s    
r
   c                    s.   dd | D }t tj|  fdd| D S )Nc                 S  s   g | ]	}|d ur|j qS r   dtype.0xr   r   r   
<listcomp>5   s    z%_cast_common_type.<locals>.<listcomp>c                   s,   g | ]}|d ur|j  kr| n|qS r   )r/   astyper0   r.   r   r   r3   7   s    $)
_functoolsreduce_numpypromote_types)xsdtypesr   r.   r   _cast_common_type4   s
   
r;   c                 C  s   | rt jS t jS r   )r   CUSPARSE_OPERATION_TRANSPOSE CUSPARSE_OPERATION_NON_TRANSPOSE)transr   r   r   _transpose_flag;   s   r?   c                 G  sR   |dkrd}n|dkrd}n|dkrd}n	|dkrd}nt tt||  }|| S )NfsdFcDz)	TypeErrorgetattrr   )namer/   argsprefixr@   r   r   r   _call_cusparseB   s   rL   csrmv)@  *  csrmvExcsrmmcsrmm2csrgeamcsrgeam2)<#  Ncsrgemmcsrgemm2)rN   .  gthrspmv'  rO   )LinuxWindowsspmmi=(  	csr2dense	csc2densecsrsort)rN   Ncscsortcoosortcoo2csr)r[   N)rU   rX   )i$,  N)i\+  N)iP-  N)csr2coocsr2csccsc2csr
csr2cscEx2
csc2csrEx2	dense2csc	dense2csrcsr2csr_compresscsrsm2csrilu02denseToSparsesparseToDensespgemmspsm)i1  N)  N)iNc                 C  s8   t | trt }|| vrd|}t|| | S | S )Nz/No version information specified for the OS: {})
isinstancedict	_platformsystemformat
ValueError)r2   os_namemsgr   r   r   _get_avail_version_from_spec   s   
r|   c                 C  s   t js
t}t }nt}t }| |vrd| }t|||  \}}t	|}t	|}|d ur5||k r5dS |d ur?||kr?dS dS )Nz1No available version information specified for {}FT)
_runtimeis_hip_available_cusparse_versionr   get_build_version_available_hipsparse_version_driverrx   ry   r|   )rI   available_versionversionr{   version_addedversion_removedr   r   r   check_availability   s    

r   returnintc                   C  s   t t S r   )r   
getVersion_deviceget_cusparse_handler   r   r   r   r      s   r      Fc                 C  s
  t dstd|du s|jjsJ |s| jn| jddd }|d t|kr+tdt }|\}}	t	| ||\} }}| j
}
|du rIt||
}t||
j}t||
j}td|
|t|| jd | jd | j|j| jj| jjj| jjj| jjj|jj|j|jj |S )a\  Matrix-vector product for a CSR-matrix and a dense vector.

    .. math::

       y = \alpha * o_a(A) x + \beta y,

    where :math:`o_a` is a transpose function when ``transa`` is ``True`` and
    is an identity function otherwise.

    Args:
        a (cupyx.cusparse.csr_matrix): Matrix A.
        x (cupy.ndarray): Vector x.
        y (cupy.ndarray or None): Vector y. It must be F-contiguous.
        alpha (float): Coefficient for x.
        beta (float): Coefficient for y.
        transa (bool): If ``True``, transpose of ``A`` is used.

    Returns:
        cupy.ndarray: Calculated ``y``.

    rM   zcsrmv is not available.Nr   dimension mismatchr   )r   RuntimeErrorflagsf_contiguousshapelenry   r   r   r;   r/   _cupyzerosr7   arrayctypesrL   r?   nnzdata_descrr   ptrindptrindices)ar2   yalphabetatransaa_shapehandlemnr/   r   r   r   rM      s,   c                 C  sv   | j j jd dkrdS | jj jd dkrdS | jj jd dkr!dS |j jd dkr+dS |dur9|j jd dkr9dS dS )a  Check if the pointers of arguments for csrmvEx are aligned or not

    Args:
        a (cupyx.cusparse.csr_matrix): Matrix A.
        x (cupy.ndarray): Vector x.
        y (cupy.ndarray or None): Vector y.

        Check if a, x, y pointers are aligned by 128 bytes as
        required by csrmvEx.

    Returns:
        bool:
        ``True`` if all pointers are aligned.
        ``False`` if otherwise.

       r   FNT)r   r   r   r   )r   r2   r   r   r   r   csrmvExIsAligned   s   r   Tc                 C  s  t dstd|du s|jjsJ | jd t|krtdt }| j\}}t	| ||\} }}| j
}	|du r>t||	}t|	}
|rHtjntj}tj}t||	j}t||	j}t| ||sdJ t|||| jd | jd | j|j|
| jj| jjj|
| jjj| jjj|jj|
|j|
|jj|
|
}t|d}|jjd dksJ t |||| jd | jd | j|j|
| jj| jjj|
| jjj| jjj|jj|
|j|
|jj|
|
|jj |S )	a  Matrix-vector product for a CSR-matrix and a dense vector.

    .. math::

       y = \alpha * A x + \beta y,

    Args:
        a (cupyx.cusparse.csr_matrix): Matrix A.
        x (cupy.ndarray): Vector x.
        y (cupy.ndarray or None): Vector y. It must be F-contiguous.
        alpha (float): Coefficient for x.
        beta (float): Coefficient for y.
        merge_path (bool): If ``True``, merge path algorithm is used.

        All pointers must be aligned with 128 bytes.

    Returns:
        cupy.ndarray: Calculated ``y``.

    rP   zcsrmvEx is not available.Nr   r   r   br   )!r   r   r   r   r   r   ry   r   r   r;   r/   r   r   r   to_cuda_dtyper   CUSPARSE_ALG_MERGE_PATHCUSPARSE_ALG_NAIVEr=   r7   r   r   r   csrmvEx_bufferSizer   r   r   r   r   r   r   emptyrP   )r   r2   r   r   r   
merge_pathr   r   r   r/   datatypealgmodetransa_flag
bufferSizebufr   r   r   rP     sN   


c                 C  sX  t dstd| j|j  krdksJ  J |jjsJ |du s(|jjs(J |s-| jn| jddd }|d |jd krBtdt }|\}}	|jd }
t	| ||\} }}|du rft
||
f| jd	}|	}|}t|| jj}t|| jj}td| j|t|| jd |
| jd | j|j| jj| jjj| jjj| jjj|jj||j|jj| |S )
a|  Matrix-matrix product for a CSR-matrix and a dense matrix.

    .. math::

       C = \alpha o_a(A) B + \beta C,

    where :math:`o_a` is a transpose function when ``transa`` is ``True`` and
    is an identity function otherwise.

    Args:
        a (cupyx.scipy.sparse.csr): Sparse matrix A.
        b (cupy.ndarray): Dense matrix B. It must be F-contiguous.
        c (cupy.ndarray or None): Dense matrix C. It must be F-contiguous.
        alpha (float): Coefficient for AB.
        beta (float): Coefficient for C.
        transa (bool): If ``True``, transpose of A is used.

    Returns:
        cupy.ndarray: Calculated C.

    rQ   zcsrmm is not available.   Nr   r   r   r   rC   )r   r   ndimr   r   r   ry   r   r   r;   r   r   r/   r7   r   r   rL   r?   r   r   r   r   r   r   r   )r   r   rD   r   r   r   r   r   r   kr   ldbldcr   r   r   rQ   V  s6    
      ?        c                 C  s  t dstd| j|j  krdksJ  J | jsJ |jjs#J |du s-|jjs-J |r3|r3J |s8| jn| jddd }|sE|jn|jddd }|d |d krYtdt	 }	|\}
}|d }t
| ||\} }}|du r|t|
|f| jd	}|jd }|jd }t|}t|}t|| jj}t|| jj}td| j|	||| jd || jd | j|j| jj| jjj| jjj| jjj|jj||j|jj| |S )
aV  Matrix-matrix product for a CSR-matrix and a dense matrix.

    .. math::

       C = \alpha o_a(A) o_b(B) + \beta C,

    where :math:`o_a` and :math:`o_b` are transpose functions when ``transa``
    and ``tranb`` are ``True`` respectively. And they are identity functions
    otherwise.
    It is forbidden that both ``transa`` and ``transb`` are ``True`` in
    cuSPARSE specification.

    Args:
        a (cupyx.scipy.sparse.csr): Sparse matrix A.
        b (cupy.ndarray): Dense matrix B. It must be F-contiguous.
        c (cupy.ndarray or None): Dense matrix C. It must be F-contiguous.
        alpha (float): Coefficient for AB.
        beta (float): Coefficient for C.
        transa (bool): If ``True``, transpose of A is used.
        transb (bool): If ``True``, transpose of B is used.

    Returns:
        cupy.ndarray: Calculated C.

    rR   zcsrmm2 is not available.r   Nr   r   r   r   rC   )r   r   r   has_canonical_formatr   r   r   ry   r   r   r;   r   r   r/   r?   r7   r   r   rL   r   r   r   r   r   r   r   )r   r   rD   r   r   r   transbr   b_shaper   r   r   r   r   r   op_aop_br   r   r   rR     s>    


c                 C  s  t dstdt| tjjjstdt	| t|tjjjs*tdt	|| j
s/J |j
s4J | j|jkr>tdt }| j\}}t| |\} }tdd}t|tj t }t|d d}	t|||| jj| j| jjj| jjj|jj|j|jjj|jjj|j|	jj|j j tt!|d}
tt!|| j"}t#|| j"j }t#|| j"j }t$d| j"||||j| jj| j| jjj| jjj| jjj|j|jj|j|jjj|jjj|jjj|j|jj|	jj|
jj tjjj||
|	f| jd}d	|_%|S )
e  Matrix-matrix addition.

    .. math::
        C = \alpha A + \beta B

    Args:
        a (cupyx.scipy.sparse.csr_matrix): Sparse matrix A.
        b (cupyx.scipy.sparse.csr_matrix): Sparse matrix B.
        alpha (float): Coefficient for A.
        beta (float): Coefficient for B.

    Returns:
        cupyx.scipy.sparse.csr_matrix: Result matrix.

    rS   zcsrgeam is not available.unsupported type (actual: {})inconsistent shapesr   ir   r   T)&r   r   rt   cupyxscipysparse
csr_matrixrG   rx   typer   r   ry   r   r   r;   r7   r   r   setPointerModeCUSPARSE_POINTER_MODE_HOSTr
   r   r   xcsrgeamNnzr   r   r   r   r   r   r   r   r   r/   r   rL   _has_canonical_format)r   r   r   r   r   r   r   r   c_descrc_indptr	c_indicesc_datarD   r   r   r   rS     sX   




c                 C  s  t dstdt| tjjjstdt	| t|tjjjs*tdt	|| j
s/J |j
s4J | j|jkr>tdt }| j\}}t| |\} }tdd}t|tj t|| jj}t|| jj}t }t|d d}	d}
td	| j||||j| jj| j| jjj | j!jj | j"jj |j|jj|j|jjj |j!jj |j"jj |j|
|	jj |
}t|tj#}t$|||| jj| j| j!jj | j"jj |jj|j|j!jj |j"jj |j|	jj |jj|jj  tt%|d}tt%|| j}td| j||||j| jj| j| jjj | j!jj | j"jj |j|jj|j|jjj |j!jj |j"jj |j|jj |	jj |jj |jj  tjjj|||	f| jd
}d|_&|S )r   rT   zcsrgeam2 is not available.r   r   r   r   r   r   csrgeam2_bufferSizeExtr   T)'r   r   rt   r   r   r   r   rG   rx   r   r   r   ry   r   r   r;   r7   r   r   r   r   r   r/   r   r
   r   r   rL   r   r   r   r   r   r   r   int8xcsrgeam2Nnzr   r   )r   r   r   r   r   r   r   r   r   r   null_ptr	buff_sizebuffr   r   rD   r   r   r   rT     sf   


c                 C  s6  t dstd| j|j  krdksJ  J | jsJ |js"J |s'| jn| jddd }|s4|jn|jddd }|d |d krHtdt }|\}}|d }	t| |\} }| j	dkse|j	dkrqt
jjj||	f| jd	S t|}
t|}td
d}t|tj t }t|d d}t||
|||	|| jj| j	| jjj| jjj|jj|j	|jjj|jjj|j|jj|jj tt |d}tt || j}t!d| j||
|||	|| jj| j	| jjj| jjj| jjj|jj|j	|jjj|jjj|jjj|j|jj|jj|jj t
jjj|||f||	fd}d|_"|S )a  Matrix-matrix product for CSR-matrix.

    math::
       C = op(A) op(B),

    Args:
        a (cupyx.scipy.sparse.csr_matrix): Sparse matrix A.
        b (cupyx.scipy.sparse.csr_matrix): Sparse matrix B.
        transa (bool): If ``True``, transpose of A is used.
        transb (bool): If ``True``, transpose of B is used.

    Returns:
        cupyx.scipy.sparse.csr_matrix: Calculated C.

    rV   zcsrgemm is not available.r   Nr   r   r   r   r.   r   r   r   T)#r   r   r   r   r   ry   r   r   r;   r   r   r   r   r   r/   r?   r7   r   r   r   r   r
   r   r   xcsrgemmNnzr   r   r   r   r   r   r   r   rL   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rD   r   r   r   rV   R  sZ    

	c                 C  s  t dstd| j|j  krdksJ  J t| tjjjs)td	t
| t|tjjjs:td	t
|| js?J |jsDJ | jd |jd krRtd|dur|jdks]J t|tjjjsntd	t
||jssJ | jd |jd ks|jd |jd krtdtjrt d	k rtd
t }| j\}}|j\}}	|du rt| |\} }n	t| ||\} }}t }
t|| jj}d}|du r|}t }d}|}|}|}n t|| jj}|j}|j}|j}|jjj }|j!jj }|j"jj }t#d| j|||	||j| jj$| j| j!jj | j"jj |jj$|j|j!jj |j"jj ||j$||||
}t%&|tj'}t&dd}t(|tj) t }t%&|d d}t*|||	|| jj$| j| j!jj | j"jj |jj$|j|j!jj |j"jj |j$||||j$|jj |jj|
|jj  t%&t+|d}t%&t+|| j}t#d| j|||	||j| jj$| j| jjj | j!jj | j"jj |jj$|j|jjj |j!jj |j"jj ||j$|||||j$|jj |jj |jj |
|jj  tjjj|||f||	fd}d|_,t-|
 |S )a  Matrix-matrix product for CSR-matrix.

    math::
       C = alpha * A * B + beta * D

    Args:
        a (cupyx.scipy.sparse.csr_matrix): Sparse matrix A.
        b (cupyx.scipy.sparse.csr_matrix): Sparse matrix B.
        d (cupyx.scipy.sparse.csr_matrix or None): Sparse matrix D.
        alpha (scalar): Coefficient
        beta (scalar): Coefficient

    Returns:
        cupyx.scipy.sparse.csr_matrix

    rW   zcsrgemm2 is not available.r   r   r   r   mismatched shapeNrs   z'd != None is supported since ROCm 4.2.0csrgemm2_bufferSizeExtr   r   r   T).r   r   r   rt   r   r   r   r   rG   rx   r   r   r   ry   r}   r~   r   r   r   r   r;   r   createCsrgemm2Infor7   r   r/   r   r
   r   r   r   r   r   r   r   rL   r   r   r   r   r   r   xcsrgemm2Nnzr   r   destroyCsrgemm2Info)r   r   rB   r   r   r   r   r   _r   infor   	beta_datad_descrd_nnzd_datad_indptr	d_indicesr   r   c_nnzr   r   r   r   rD   r   r   r   rW     s    


(




	
c                 C     t dstd| j}|jdv sJ |du r tj| j|dd}n|jjs&J t	
 }td| j|| jd | jd | jj| jjj| jjj| jjj|jj| jd  |S )	a!  Converts CSR-matrix to a dense matrix.

    Args:
        x (cupyx.scipy.sparse.csr_matrix): A sparse matrix to convert.
        out (cupy.ndarray or None): A dense matrix to store the result.
            It must be F-contiguous.

    Returns:
        cupy.ndarray: Converted result.

    r_   zcsr2dense is not available.fdFDNrC   r/   orderr   r   )r   r   r/   charr   r   r   r   r   r   r   rL   r   r   r   r   r   r   r2   outr/   r   r   r   r   r_         c                 C  r   )	a!  Converts CSC-matrix to a dense matrix.

    Args:
        x (cupyx.scipy.sparse.csc_matrix): A sparse matrix to convert.
        out (cupy.ndarray or None): A dense matrix to store the result.
            It must be F-contiguous.

    Returns:
        cupy.ndarray: Converted result.

    r`   zcsc2dense is not available.r   NrC   r   r   r   )r   r   r/   r   r   r   r   r   r   r   r   rL   r   r   r   r   r   r   r   r   r   r   r`      r   c                 C    t dstd| j}|dkrdS t }| j\}}t||||| jj	j
| jj	j
}t|d}t|d}| j	 }t|||j	j
 t||||| jj| jj	j
| jj	j
|j	j
|j	j
	 t drwtd| j|||j	j
| j	j	j
|j	j
tj dS t|| j	}	t|}
t||
j|	j dS )zzSorts indices of CSR-matrix in place.

    Args:
        x (cupyx.scipy.sparse.csr_matrix): A sparse matrix to sort.

    ra   zcsrsort is not available.r   Nr   r   rY   )r   r   r   r   r   r   r   xcsrsort_bufferSizeExtr   r   r   r   r   r   copycreateIdentityPermutationxcsrsortr   r   rL   r/   CUSPARSE_INDEX_BASE_ZEROSpVecDescriptorr   DnVecDescriptorgatherdescr2   r   r   r   r   buffer_sizer   P	data_origdesc_xdesc_yr   r   r   ra   @  8   



c                 C  r   )zzSorts indices of CSC-matrix in place.

    Args:
        x (cupyx.scipy.sparse.csc_matrix): A sparse matrix to sort.

    rb   zcscsort is not available.r   Nr   r   rY   )r   r   r   r   r   r   r   xcscsort_bufferSizeExtr   r   r   r   r   r   r   r   xcscsortr   r   rL   r/   r   r   r   r   r   r   r   r   r   r   rb   f  r  rc              
   C  sz  t dstd| j}|dkrdS t }| j\}}t||||| jj	j
| jj	j
}t|d}t|d}| j	 }	t|||j	j
 |dkr_t||||| jj	j
| jj	j
|j	j
|j	j
 n|dkrzt||||| jj	j
| jj	j
|j	j
|j	j
 ntd	| jjd
krt drtd| j|||	j	j
| j	j	j
|j	j
tj nt|| j	}
t|	}t||j|
j |dkrd| _dS dS )zSorts indices of COO-matrix in place.

    Args:
        x (cupyx.scipy.sparse.coo_matrix): A sparse matrix to sort.
        sort_by (str): Sort the indices by row ('r', default) or column ('c').

    rc   zcoosort is not available.r   Nr   r   r  rD   z!sort_by must be either 'r' or 'c'?rY   F)r   r   r   r   r   r   r   xcoosort_bufferSizeExtrowr   r   colr   r   r   r   xcoosortByRowxcoosortByColumnry   r/   r   rL   r   r   r   r   r   r   r   )r2   sort_byr   r   r   r   r   r   r   r   r   r   r   r   r   rc     sL   




c                 C  s   t  }| jd }| j}|dkrt|d d}nt|d d}t|| j	j
j|||j
jtj tjjj| j
| j|f| jdS )Nr   r   r   r   )r   r   r   r   r   r   r   r   xcoo2csrr  r   r   r   r   r   r   r   r  )r2   r   r   r   r   r   r   r   rd        

c                 C  s   t  }| jd }| j}|dkrt|d d}nt|d d}t|| j	j
j|||j
jtj tjjj| j
| j|f| jdS )Nr   r   r   r   )r   r   r   r   r   r   r   r   r  r  r   r   r   r   r   r   
csc_matrixr  )r2   r   r   r   r   r   r   r   coo2csc  r  r  c                 C  sp   t dstdt }| jd }| j}t|d}t	|| j
jj|||jjtj tjjj|||ff| jdS )aD  Converts a CSR-matrix to COO format.

    Args:
        x (cupyx.scipy.sparse.csr_matrix): A matrix to be converted.
        data (cupy.ndarray): A data array for converted data.
        indices (cupy.ndarray): An index array for converted data.

    Returns:
        cupyx.scipy.sparse.coo_matrix: A converted matrix.

    re   zcsr2coo is not available.r   r   r   )r   r   r   r   r   r   r   r   r   xcsr2coor   r   r   r   r   r   r   
coo_matrix)r2   r   r   r   r   r   r  r   r   r   re     s   
re   c                 C  s   t dstdt }| j\}}| j}t|| j}t|d}|dkr.t	|d d}n+t|d d}t
d| j||||| jjj| jjj| jjj|jj|jj|jjtjtj tjjj|||f| jdS )Nrf   csr2csc is not available.r   r   r   r   )r   r   r   r   r   r   r   r   r/   r   rL   r   r   r   r   r   CUSPARSE_ACTION_NUMERICr   r   r   r   r  r2   r   r   r   r   r   r   r   r   r   r   rf     *   
rf   c                 C  s<  t dstdt }| j\}}| j}t|| j}t|d}|dkr.t	|d d}nct|d d}t
| j}tj}	tj}
tj}t||||| jjj| jjj| jjj|jj|jj|jj||	|
|}t|tj}t||||| jjj| jjj| jjj|jj|jj|jj||	|
||jj tjjj|||f| jdS )Nrh   zcsr2cscEx2 is not available.r   r   r   r   )r   r   r   r   r   r   r   r   r/   r   r   r   r   r  r   CUSPARSE_CSR2CSC_ALG1csr2cscEx2_bufferSizer   r   r   r   r7   r   rh   r   r   r   r  r2   r   r   r   r   r   r   r   x_dtypeactionibasealgor   bufferr   r   r   rh     8   
rh   c                 C  s`   t  }| jd }| j}t|d}t|| jj	j
|||j	j
tj tjjj|||ff| jdS )aD  Converts a CSC-matrix to COO format.

    Args:
        x (cupyx.scipy.sparse.csc_matrix): A matrix to be converted.
        data (cupy.ndarray): A data array for converted data.
        indices (cupy.ndarray): An index array for converted data.

    Returns:
        cupyx.scipy.sparse.coo_matrix: A converted matrix.

    r   r   r   )r   r   r   r   r   r   r   r  r   r   r   r   r   r   r   r  )r2   r   r   r   r   r   r  r   r   r   csc2coo,  s   
r  c                 C  s   t dstdt }| j\}}| j}t|| j}t|d}|dkr.t	|d d}n+t|d d}t
d| j||||| jjj| jjj| jjj|jj|jj|jjtjtj tjjj|||f| jdS )Nrg   r  r   r   r   rf   r   )r   r   r   r   r   r   r   r   r/   r   rL   r   r   r   r   r   r  r   r   r   r   r   r  r   r   r   rg   D  r  rg   c                 C  s<  t dstdt }| j\}}| j}t|| j}t|d}|dkr.t	|d d}nct|d d}t
| j}tj}	tj}
tj}t||||| jjj| jjj| jjj|jj|jj|jj||	|
|}t|tj}t||||| jjj| jjj| jjj|jj|jj|jj||	|
||jj tjjj|||f| jdS )Nri   zcsc2csrEx2 is not available.r   r   r   r   )r   r   r   r   r   r   r   r   r/   r   r   r   r   r  r   r  r  r   r   r   r   r7   r   rh   r   r   r   r   r  r   r   r   ri   \  r  ri   c                 C  s  t dstd| jdksJ t| } tjddd}t }| j	\}}t
 }t|d}td| j|tj|||j| jj||jj|jj t|}t|| j}t|d d}t|d}	td| j||||j| jj||jj|jj|	jj|jj tjjj||	|f| j	d	}
d
|
_|
S )zConverts a dense matrix in CSC format.

    Args:
        x (cupy.ndarray): A matrix to be converted.

    Returns:
        cupyx.scipy.sparse.csc_matrix: A converted matrix.

    rj   zdense2csc is not available.r   r   r   r.   r   r   r   T)r   r   r   r   asfortranarrayr7   r   r   r   r   r
   r   rL   r/   r   CUSPARSE_DIRECTION_COLUMNr   r   r   r   r   r   r   r   r  r   )r2   r   r   r   r   r   nnz_per_colr   r   r   cscr   r   r   rj   z  s6   



rj   c                 C  s,  t dstd| jdksJ t| } tjddd}t }| j	\}}t
 }t|d}td| j|tj|||j| jj||jj|jj t|}tjrT|dkrTtd	t|| j}t|d
 d}t|d}	td| j||||j| jj||jj|jj|jj|	jj tjjj||	|f| j	d}
d|
_|
S )zConverts a dense matrix in CSR format.

    Args:
        x (cupy.ndarray): A matrix to be converted.

    Returns:
        cupyx.scipy.sparse.csr_matrix: A converted matrix.

    rk   zdense2csr is not available.r   r   r   r.   r   r   @hipSPARSE currently cannot handle sparse matrices with null ptrsr   r   T)r   r   r   r   r   r7   r   r   r   r   r
   r   rL   r/   r   CUSPARSE_DIRECTION_ROWr   r   r   r   r   r}   r~   ry   r   r   r   r   r   )r2   r   r   r   r   r   nnz_per_rowr   r   r   csrr   r   r   rk     s<   



rk   c           
      C  s   t dstd| jjdv sJ t }| j\}}t|d}t	d| j||| j
j| jjj| jjj|jj|	}t|| j}t|d d}t|d}	t	d| j|||| j
j| jjj| jjj| jjj| j|jj|jj|	jj|jj| tjjj||	|f| jdS )Nrl   z"csr2csr_compress is not available.r   r   nnz_compressr   r   )r   r   r/   r   r   r   r   r   r   rL   r   r   r   r   r   r   r   r   r   r   r   r   )
r2   tolr   r   r   r&  r   r   r   r   r   r   r   rl     s0   

rl   c                 C  s.   | dkrt jS | dkrt jS | dkrt jS t)Nuint16int32int64)r   CUSPARSE_INDEX_16UCUSPARSE_INDEX_32ICUSPARSE_INDEX_64IrG   r.   r   r   r   _dtype_to_IndexType  s   r0  c                   @  s,   e Zd ZdddZejfddZdd ZdS )	BaseDescriptorNc                 C  s   || _ || _|| _d S r   )r   getdestroy)r   r   r2  	destroyerr   r   r   r     s   
zBaseDescriptor.__init__c                 C  sB   | rd S | j d u rd | _d S | jd ur|  | j d | _d S d S r   )r3  r   r   r   r   r   r      s   



zBaseDescriptor.__del__c                 C  s    | j d urt|  | j|S tr   )r2  rH   r   AttributeError)r   rI   r   r   r   __getattr__	  s   
zBaseDescriptor.__getattr__)NN)r*   r+   r,   r   r	   r   r   r6  r   r   r   r   r1    s    
	r1  c                   @  s    e Zd Zedd Zdd ZdS )SpMatDescriptorc           	      C  s:  t jj|s	J |j\}}tj}t|j	}|j
dkr@t|||j|jjj|jjj|jjjt|jj	t|jj	||
}tj}nT|j
dkrdt|||j|jjj|jjj|jjjt|jj	||	}tj}n0|j
dkrt|||j|jjj|jjj|jjjt|jj	t|jj	||
}d }ntd
|j
tj}t|||S )Nr'  coor#  z3csr, csc and coo format are supported (actual: {}).)r   r   r   issparser   r   r   r   r   r/   rx   	createCsrr   r   r   r   r   r0  csrGet	createCoor  r  cooGet	createCscry   destroySpMatr7  )	r   r   rowscolsidx_base
cuda_dtyper   r2  r3  r   r   r   r     s<   



zSpMatDescriptor.createc                 C  s   t | j|| d S r   )r   spMatSetAttributer   )r   	attributer   r   r   r   set_attribute/  s   zSpMatDescriptor.set_attributeN)r*   r+   r,   r-   r   rF  r   r   r   r   r7    s    
r7  c                   @     e Zd Zedd ZdS )r   c              	   C  sP   |j }t|j}t|||jj|jjt|jtj	|}tj
}tj}t|||S r   )sizer   r   r/   r   createSpVecr   r   r0  r   spVecGetdestroySpVecr   )r   idxr2   r   rC  r   r2  r3  r   r   r   r   5  s   zSpVecDescriptor.createNr*   r+   r,   r-   r   r   r   r   r   r   3      r   c                   @  rG  )r   c                 C  s8   t |j}t|j|jj|}tj}tj	}t
|||S r   )r   r   r/   r   createDnVecrH  r   r   dnVecGetdestroyDnVecr   )r   r2   rC  r   r2  r3  r   r   r   r   D  s
   zDnVecDescriptor.createNrM  r   r   r   r   r   B  rN  r   c                   @  rG  )DnMatDescriptorc           	      C  sf   |j dksJ |jjsJ |j\}}|}t|j}t||||j	j
|tj}tj}tj}t|||S )Nr   )r   r   r   r   r   r   r/   r   createDnMatr   r   CUSPARSE_ORDER_COLdnMatGetdestroyDnMatrR  )	r   r   r@  rA  ldrC  r   r2  r3  r   r   r   r   O  s   
zDnMatDescriptor.createNrM  r   r   r   r   rR  M  rN  rR  c                 C  s  t dstdt| tjjjr+| j}t|tjjjs&d	t
|}t||} | }t| tjjjtjjjfsAtd	t
| |sF| jn| jddd }|d t|krZtd| js_J |\}	}
t| ||\} }}|du rxt|	| j}n
t||	krtd| jd	kr|d	 |S t| }t|}t|}t }t|}t|| jj}t|| jj}t !| j}t"j#}t"$|||j%|j&|j&|j%|j&||	}t'|tj(}t")|||j%|j&|j&|j%|j&|||j%j*
 |S )
a  Multiplication of sparse matrix and dense vector.

    .. math::

        y = \alpha * op(A) x + \beta * y

    Args:
        a (cupyx.scipy.sparse.csr_matrix, csc_matrix or coo_matrix):
            Sparse matrix A
        x (cupy.ndarray): Dense vector x
        y (cupy.ndarray or None): Dense vector y
        alpha (scalar): Coefficient
        beta (scalar): Coefficient
        transa (bool): If ``True``, op(A) = transpose of A.

    Returns:
        cupy.ndarray
    rZ   zspmv is not available."aT must be csr_matrix (actual: {})r   Nr   r   r   r   )+r   r   rt   r   r   r   r  Tr   rx   r   rG   r  r   r   ry   r   r;   r   r   r/   r   fillr7  r   r   r   r   r?   r7   r   r   r   r   r   CUSPARSE_MV_ALG_DEFAULTspMV_bufferSizer   r   r   r   spMVr   )r   r2   r   r   r   r   aTr{   r   r   r   desc_ar   r   r   r   rC  algr   r   r   r   r   rZ   ]  sX   





c                 C  s`  t dstd| j|j  krdksJ  J |jjsJ |du s(|jjs(J t| tjjj	rK| j
}t|tjjjsFdt|}t||} | }t| tjjjtjjjfsatdt| |sf| jn| jddd }	|ss|jn|jddd }
|	d |
d	 krtd
| jsJ |	\}}|
\}}t| ||\} }}|du rt||f| jd}n|jd	 |ks|jd |krtd
| jd	kr|d	 |S t| }t|}t|}t }t|}t|}t || jj!}t || jj!}t"#| j}t$j%}t$&||||j'|j(|j(|j'|j(||
}t)|tj*}t$+||||j'|j(|j(|j'|j(|||j'j,}|S )a  Multiplication of sparse matrix and dense matrix.

    .. math::

        C = \alpha * op(A) op(B) + \beta * C

    Args:
        a (cupyx.scipy.sparse.csr_matrix, csc_matrix or coo_matrix):
            Sparse matrix A
        b (cupy.ndarray): Dense matrix B
        c (cupy.ndarray or None): Dense matrix C
        alpha (scalar): Coefficient
        beta (scalar): Coefficient
        transa (bool): If ``True``, op(A) = transpose of A.
        transb (bool): If ``True``, op(B) = transpose of B.

    Returns:
        cupy.ndarray
    r^   zspmm is not available.r   NrX  r   r   r   r   r   rC   )-r   r   r   r   r   rt   r   r   r   r  rY  r   rx   r   rG   r  r   ry   r   r;   r   r   r/   r   rZ  r7  r   rR  r   r   r?   r7   r   r   r   r   r   CUSPARSE_MM_ALG_DEFAULTspMM_bufferSizer   r   r   r   spMMr   )r   r   rD   r   r   r   r   r^  r{   r   r   r   r   r   r   r_  desc_bdesc_cr   r   r   rC  r`  r   r   r   r   r   r^     sf    






c                 C  s6  t dstdtjj| stjj| stdt|t	j
s$td|jdvr-td| jd | jd   krC|jd ksHtd	 td	| j|jkrRtd
|du rZtj}n|du rbtj}ntd||du rqtj}	n|du rytj}	ntd||du rd}
n|du rd}
ntd||du rtj}n|du rtj}ntd|| j}|jdkrd}n|jdkrd}n|jdkrd}n|jdkrd}ntd|tt|d }tt|d }tt|d }|du s|dkrtj}n(|du s|dkrtj}n|dkr|jdv rtj}ntj}ntd |tjj| rF|tjkr1td!| j} tjj| s>J d| }d| }| jd }|jdkrSdn|jd }|jrbtj}|}n|jrltj}|}ntd"t  }t!j"||d#}t#$ }|%tj& |'tj( |)| |*|	 t+ }|||
||||| j,|j-j.|j/| j.j.j0| j1j.j0| j2j.j0|j.j0|||}t	j3|ft!j4d#}|||
||||| j,|j-j.|j/| j.j.j0| j1j.j0| j2j.j0|j.j0||||j.j0 |||
||||| j,|j-j.|j/| j.j.j0| j1j.j0| j2j.j0|j.j0||||j.j0 t56 7  t8| d$S )%aV  Solves a sparse triangular linear system op(a) * x = alpha * b.

    Args:
        a (cupyx.scipy.sparse.csr_matrix or cupyx.scipy.sparse.csc_matrix):
            Sparse matrix with dimension ``(M, M)``.
        b (cupy.ndarray): Dense vector or matrix with dimension ``(M)`` or
            ``(M, K)``.
        alpha (float or complex): Coefficient.
        lower (bool):
            True: ``a`` is lower triangle matrix.
            False: ``a`` is upper triangle matrix.
        unit_diag (bool):
            True: diagonal part of ``a`` has unit elements.
            False: diagonal part of ``a`` has non-unit elements.
        transa (bool or str): True, False, 'N', 'T' or 'H'.
            'N' or False: op(a) == ``a``.
            'T' or True: op(a) == ``a.T``.
            'H': op(a) == ``a.conj().T``.
        blocking (bool):
            True: blocking algorithm is used.
            False: non-blocking algorithm is used.
        level_info (bool):
            True: solves it with level information.
            False: solves it without level information.

    Note: ``b`` will be overwritten.
    rm   zcsrsm2 is not available.z"a must be CSR or CSC sparse matrixzb must be cupy.ndarray)r   r   b.ndim must be 1 or 2r   r   zinvalid shapedtype mismatchTFUnknown lower (actual: {})Unknown unit_diag (actual: {})zUnknown blocking (actual: {})Unknown level_info (actual: {})r@   rA   rB   rC   rD   rE   rF   Invalid dtype (actual: {})csrsm2_bufferSizeExtcsrsm2_analysiscsrsm2_solveNrY  HfdzUnknown transa (actual: {})z@If matrix is CSC format and complex dtype,transa must not be 'H''b must be F-contiguous or C-contiguous.r.   N)9r   r   r   r   r   isspmatrix_csrisspmatrix_cscry   rt   r   ndarrayr   r   r/   rG   r   CUSPARSE_FILL_MODE_LOWERCUSPARSE_FILL_MODE_UPPERrx   CUSPARSE_DIAG_TYPE_NON_UNITCUSPARSE_DIAG_TYPE_UNITCUSPARSE_SOLVE_POLICY_NO_LEVELCUSPARSE_SOLVE_POLICY_USE_LEVELr   rH   r=   r<   &CUSPARSE_OPERATION_CONJUGATE_TRANSPOSErY  _f_contiguous_c_contiguousr   r   r7   r   r
   r   r   CUSPARSE_MATRIX_TYPE_GENERALr#   r   r&   r)   createCsrsm2Infor   r   r   r   r   r   r   r   r   _streamget_current_streamsynchronizedestroyCsrsm2Info)r   r   r   lower	unit_diagr   blocking
level_infor%   r(   r  policyr/   thelperanalysissolver   nrhsr   r   r   a_descr   ws_sizewsr   r   r   rm     s   
$







rm   c                 C  s`  t dstdtjj| std| jd | jd kr%td	| j|du r-t
j}n|du r5t
j}ntd		|| j}|jd
krGd}n|jdkrOd}n|jdkrWd}n|jdkr_d}ntd	|tt
|d }tt
|d }tt
|d }tt
d}t }	| jd }
| j}t }|t
j |t
j t
 }||	|
||j| jjj| jjj| jjj|}tj |ft!j"d}t!j dt!j#d}||	|
||j| jjj| jjj| jjj|||jj
 z
||	||j$j W n t%y   td	|d w ||	|
||j| jjj| jjj| jjj|||jj
 z||	||j$j W dS  t%y/   td	|d w )a  Computes incomplete LU decomposition for a sparse square matrix.

    Args:
        a (cupyx.scipy.sparse.csr_matrix):
            Sparse matrix with dimension ``(M, M)``.
        level_info (bool):
            True: solves it with level information.
            False: solves it without level information.

    Note: ``a`` will be overwritten. This function does not support fill-in
        (only ILU(0) is supported) nor pivoting.
    rn   zcsrilu02 is not available.za must be CSR sparse matrixr   r   zinvalid shape (a.shape: {})FTrj  r@   rA   rB   rC   rD   rE   rF   rk  csrilu02_bufferSizecsrilu02_analysisxcsrilu02_zeroPivotr.   r   za({0},{0}) is missingzu({0},{0}) is zeroN)&r   r   r   r   r   rs  rG   r   ry   rx   r   rz  r{  r/   r   rH   r   r   r   r
   r   r   r  r#   r   createCsrilu02Infor   r   r   r   r   r   r   r7   r   r+  r   	Exception)r   r  r  r/   r  r  r  r  checkr   r   r   r   r   r  r  positionr   r   r   rn   ~  sj   





rn   r'  c                 C  sl  t dstd| jdksJ | jjdv sJ t| } t| }|dkr1t	j
jj| j| jd}n'|dkrAt	j
jj| j| jd}n|dkrQt	j
jj| j| jd}ntd	|t|}tj}t }t||j|j|}t|tj}t||j|j||jj tjd
dd}	tjd
dd}
tjd
dd}t |j|	j!j|
j!j|j!j t"|}t#j$r|d
krt%d|dkr|j&}t|d}t|| j}t	j
jj|||f| jd}nH|dkr|j&}t|d}t|| j}t	j
jj|||f| jd}n&|dkrt'|d}t'|d}t|| j}t	j
jj|||ff| jd}t|}t(||j|j||jj d|_)|S )a0  Converts a dense matrix into a CSR, CSC or COO format.

    Args:
        x (cupy.ndarray): A matrix to be converted.
        format (str): Format of converted matrix. It must be either 'csr',
            'csc' or 'coo'.

    Returns:
        cupyx.scipy.sparse.spmatrix: A converted sparse matrix.

    ro   zdenseToSparse is not available.r   r   r'  r.   r#  r8  zunsupported format (actual: {})r   r,  r$  r   r   T)*r   r   r   r/   r   r   r   rR  r   r   r   r   r   r   r  r  rG   rx   r7  r   "CUSPARSE_DENSETOSPARSE_ALG_DEFAULTr   r   denseToSparse_bufferSizer   r   r   denseToSparse_analysisr   r   r7   r   spMatGetSizer   r   r}   r~   ry   r   r   denseToSparse_convertr   )r2   rx   r   r   r   r  r   r   r   num_rows_tmpnum_cols_tmpr   r   r   r   r  r  r   r   r   ro     st   







ro   c           	      C  s   t dstd| j}|jdv sJ |du r tj| j|dd}n|jjs&J |j|ks-J t	
| }t
|}tj}t }t||j|j|}t|tj}tjr[| jdkr[tdt||j|j||jj |S )	a*  Converts sparse matrix to a dense matrix.

    Args:
        x (cupyx.scipy.sparse.spmatrix): A sparse matrix to convert.
        out (cupy.ndarray or None): A dense matrix to store the result.
            It must be F-contiguous.

    Returns:
        cupy.ndarray: A converted dense matrix.

    rp   zsparseToDense is not available.r   NrC   r   r   r$  )r   r   r/   r   r   r   r   r   r   r7  r   rR  r   "CUSPARSE_SPARSETODENSE_ALG_DEFAULTr   r   sparseToDense_bufferSizer   r   r   r}   r~   r   ry   rp   r   r   )	r2   r   r/   r   desc_outr  r   r   r   r   r   r   rp     s.   




rp   c                 C  s  t dstd|du rd}n|du rd}n|dvr"td| d	tjj| r*n6tjj| rT|dkr;| j} d}n|dkrE| j} d}n|d
krP| 	 j} d}| }ntjj
| r\ntd| jseJ |jdkrsd}|dd}n|jdkr{d}ntd| jd | jd   kr|jd kstd td| j}|jdvrtd|||jkrtd|du rtj}n|du rtj}ntd||du rtj}	n|du rtj}	ntd||dkrtj}
n|dkrtj}
n|jdv rtj}
ntj}
|jrtj}n|jrt dk rtd|j}tj}ntd| j\}}|tjkr/|j\}}n|j\}}||f}tj|| jdd}t ! }t"#| }t$#|}t$#|}t% }t&j'||jdj(}t)*|j}tj+}zb|,tj-| |,tj.|	 t/||
||j0|j1|j1|j1|||
}tj2|tj3d}t4||
||j0|j1|j1|j1||||j0j5 t6||
||j0|j1|j1|j1||||j0j5 |r|d}|W t7| S t7| w )a  Solves a sparse triangular linear system op(a) * x = alpha * op(b).

    Args:
        a (cupyx.scipy.sparse.csr_matrix or cupyx.scipy.sparse.coo_matrix):
            Sparse matrix with dimension ``(M, M)``.
        b (cupy.ndarray): Dense matrix with dimension ``(M, K)``.
        alpha (float or complex): Coefficient.
        lower (bool):
            True: ``a`` is lower triangle matrix.
            False: ``a`` is upper triangle matrix.
        unit_diag (bool):
            True: diagonal part of ``a`` has unit elements.
            False: diagonal part of ``a`` has non-unit elements.
        transa (bool or str): True, False, 'N', 'T' or 'H'.
            'N' or False: op(a) == ``a``.
            'T' or True: op(a) == ``a.T``.
            'H': op(a) == ``a.conj().T``.
    rr   zspsm is not available.Fro  TrY  NTHzUnknown transa (actual: )rp  z'a must be CSR, CSC or COO sparse matrixr   r   r   rf  r   r   r   rk  rg  rh  ri  rq  i-  zb must be F-contiguous.rr  r@   r   r.   )8r   r   ry   r   r   r   rs  rt  rY  conjisspmatrix_coor   r   reshaper   r/   r   rG   rx   r   rv  rw  rx  ry  r=   r<   r|  r}  r~  r   r   r   r   r   r7  r   rR  spSM_createDescrr7   r   r   r   r   CUSPARSE_SPSM_ALG_DEFAULTrF  CUSPARSE_SPMAT_FILL_MODECUSPARSE_SPMAT_DIAG_TYPEspSM_bufferSizer   r   r   r   spSM_analysisr   
spSM_solvespSM_destroyDescr)r   r   r   r  r  r   is_b_vectorr/   r%   r(   r   r   r   r   r   c_shaperD   r   mat_amat_bmat_c
spsm_descrrC  r  r   r   r   r   r   rr   5  s   



$









rr   c                 C  s  t dstd| j|j  krdksJ  J t| tjjjs)td	t
| t|tjjjs:td	t
|| js?J |jsDJ | jd |jd krRtd| j\}}|j\}}t| |\} }||f}tjjj|| jd}t }	t| }
t|}t|}t }tj}tj}tj||jdj}tjd|jdj}t|j}tj}d}z7t|	|||j|
j|j|j|j|||d|}t !|t j"}t|	|||j|
j|j|j|j|||||jj# W nS tj$y5 } zEt% d	k r|tj&}t|	|||j|
j|j|j|j|||d|}t !|t j"}t|	|||j|
j|j|j|j|||||jj# W Y d
}~nd
}~ww t'|	|||j|
j|j|j|j|||d|}t !|t j"}t'|	|||j|
j|j|j|j|||||jj# tjddd}tjddd}tjddd}t(|j|jj|jj|jj |d t)|ksJ |d t)|ksJ t)|}|j*}t !|d}t !||j}t+|j|jj#|jj#|jj# t,|	|||j|
j|j|j|j||| tjjj|||f|d}t-| |S )a+  Matrix-matrix product for CSR-matrix.

    math::
       C = alpha * A * B

    Args:
        a (cupyx.scipy.sparse.csr_matrix): Sparse matrix A.
        b (cupyx.scipy.sparse.csr_matrix): Sparse matrix B.
        alpha (scalar): Coefficient

    Returns:
        cupyx.scipy.sparse.csr_matrix

    rq   zspgemm is not available.r   r   r   r   r   r.   rX   Nr,  r   r   ).r   r   r   rt   r   r   r   r   rG   rx   r   r   r   ry   r;   r/   r   r   r7  r   r   spGEMM_createDescrr=   r7   r   r   r   r   CUSPARSE_SPGEMM_DEFAULTspGEMM_workEstimationr   r   r   r   r   r   CuSparseErrorr   CUSPARSE_SPGEMM_ALG2spGEMM_computer  r   r   csrSetPointersspGEMM_copyspGEMM_destroyDescr)r   r   r   r   r   r   r   r  rD   r   r  r  r  spgemm_descrr   r   r   rC  r  r   
buff1_sizebuff1cse
buff2_sizebuff2
c_num_rows
c_num_colsr   r   r   r   r   r   r   rq     s    









rq   )r   r   )Nr   r   Fr   )Nr   r   T)Nr   r   FF)r   r   )FF)Nr   r   )r  )Nr   r   FF)r   TFFTF)F)r'  )r   TFFr  )N
__future__r   	functoolsr5   numpyr7   platformrv   cupyr   cupy_backends.cuda.apir   r   r   r}   cupy_backends.cuda.libsr   r   
cupy._corer   	cupy.cudar   r   r   r  r	   cupyx.scipy.sparser   r
   r;   r?   rL   r   infr   r|   memoizer   r   rM   r   rP   rQ   rR   rS   rT   rV   rW   r_   r`   ra   rb   rc   rd   r  re   rf   rh   r  rg   ri   rj   rk   rl   r0  r1  r7  r   r   rR  rZ   r^   rm   rn   ro   rp   rr   rq   r   r   r   r   <module>   sH   !	'
	
%



2

D
8
?
@
E
E
i
  &
&1*.$

CL
 

G
H
( #