o
    X۷i5                  	   @  s   d dl m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d	dddd
ddZddd	ddddddddZddd	dddd
ddZdd Zdd Zdd ZdS )    )annotationsN)cublas)_dtype)device)_csr)
_interfacegh㈵>        )rtolatolmaxiterMcallbackc                C  s^  t | |||\} }}}| j}	|j}
| jd }|du r|d }|dkr)t|dfS tj|}|dkr7|dfS tt||t| }||	| }d}d}||k r|
|}|}t	
||}|dkrc|}n
|| }|||  }|	|}|t	
|| }|||  }|||  }|d7 }|dur|| t	|}||krn||k sPd}||kr||ks|}||fS )a  Uses Conjugate Gradient iteration to solve ``Ax = b``.

    Args:
        A (ndarray, spmatrix or LinearOperator): The real or complex matrix of
            the linear system with shape ``(n, n)``. ``A`` must be a hermitian,
            positive definitive matrix with type of :class:`cupy.ndarray`,
            :class:`cupyx.scipy.sparse.spmatrix` or
            :class:`cupyx.scipy.sparse.linalg.LinearOperator`.
        b (cupy.ndarray): Right hand side of the linear system with shape
            ``(n,)`` or ``(n, 1)``.
        x0 (cupy.ndarray): Starting guess for the solution.
        rtol, atol (float): Tolerance for convergence.
        maxiter (int): Maximum number of iterations.
        M (ndarray, spmatrix or LinearOperator): Preconditioner for ``A``.
            The preconditioner should approximate the inverse of ``A``.
            ``M`` must be :class:`cupy.ndarray`,
            :class:`cupyx.scipy.sparse.spmatrix` or
            :class:`cupyx.scipy.sparse.linalg.LinearOperator`.
        callback (function): User-specified function to call after each
            iteration. It is called as ``callback(xk)``, where ``xk`` is the
            current solution vector.

    Returns:
        tuple:
            It returns ``x`` (cupy.ndarray) and ``info`` (int) where ``x`` is
            the converged solution and ``info`` provides convergence
            information.

    .. seealso:: :func:`scipy.sparse.linalg.cg`
    r   N
      )_make_systemmatvecshapecupy
empty_likelinalgnormmaxfloatr   dotcnrm2)Abx0r	   r
   r   r   r   xr   psolvenb_normritersrhozrho1pbetaqalpharesidinfo r-   Z/home/ubuntu/vllm_env/lib/python3.10/site-packages/cupyx/scipy/sparse/linalg/_iterative.pycg   sL    

r/   )r	   r
   restartr   r   r   callback_typec                C  s  t | |||\} }}
}| j}|j}| jd }|dkr!t|dfS tj|}|dkr/|dfS tt||t| }|du rB|d }|du rHd}t	||}|	du rSd}	|	dvr^t
d|	|du rdd}	tj||f| jdd	}tj|d
 |f| jdd	}tj|d
 f| jd}t|}d}	 ||
}||| }t|}|	dkr|| n|	dkr|dkr|||  ||ks||krnr|| }||dddf< ||d< t|D ]A}||}||}|||\|d|d
 |f< }tj|||d
 |f d |d
 |k r|||d
 |f  }||dd|d
 f< qtjt||}t|d }|
|| 7 }
||7 }qd}||kr=||ks=|}||fS )a  Uses Generalized Minimal RESidual iteration to solve ``Ax = b``.

    Args:
        A (ndarray, spmatrix or LinearOperator): The real or complex
            matrix of the linear system with shape ``(n, n)``. ``A`` must be
            :class:`cupy.ndarray`, :class:`cupyx.scipy.sparse.spmatrix` or
            :class:`cupyx.scipy.sparse.linalg.LinearOperator`.
        b (cupy.ndarray): Right hand side of the linear system with shape
            ``(n,)`` or ``(n, 1)``.
        x0 (cupy.ndarray): Starting guess for the solution.
        rtol, atol (float): Tolerance for convergence.
        restart (int): Number of iterations between restarts. Larger values
            increase iteration cost, but may be necessary for convergence.
        maxiter (int): Maximum number of iterations.
        M (ndarray, spmatrix or LinearOperator): Preconditioner for ``A``.
            The preconditioner should approximate the inverse of ``A``.
            ``M`` must be :class:`cupy.ndarray`,
            :class:`cupyx.scipy.sparse.spmatrix` or
            :class:`cupyx.scipy.sparse.linalg.LinearOperator`.
        callback (function): User-specified function to call on every restart.
            It is called as ``callback(arg)``, where ``arg`` is selected by
            ``callback_type``.
        callback_type (str): 'x' or 'pr_norm'. If 'x', the current solution
            vector is used as an argument of callback function. if 'pr_norm',
            relative (preconditioned) residual norm is used as an argument.

    Returns:
        tuple:
            It returns ``x`` (cupy.ndarray) and ``info`` (int) where ``x`` is
            the converged solution and ``info`` provides convergence
            information.

    Reference:
        M. Wang, H. Klie, M. Parashar and H. Sudan, "Solving Sparse Linear
        Systems on NVIDIA Tesla GPUs", ICCS 2009 (2009).

    .. seealso:: :func:`scipy.sparse.linalg.gmres`
    r   Nr      pr_norm)r   r3   zUnknown callback_type: {}F)dtypeorderr   r5   Tr   )out)r   r   r   r   r   r   r   r   r   min
ValueErrorformatemptyr5   zerosnumpy_make_compute_hur   r   rangelstsqasnumpyarray)r   r   r   r	   r
   r0   r   r   r   r1   r   r   r   r    r!   VHe
compute_hur#   mxr"   r_normvjr%   uretyr,   r-   r-   r.   gmresZ   sr   (



rO   c                C  s  t | |||\} }}}| j}	|j}
| jd }|dkr!t|dfS tj|}|dkr/|dfS tt||t| }|du rB|d }||	| }t	||}|
 }|}|
 }d}	 |
|}|	|}t	||}|| }|||  }|
|| }||| 7 }|	|}||| 8 }tj|}|d7 }|dur|| ||ks||krn#t	||}|| }|}|||  }||9 }||7 }||9 }||7 }q[d}||kr||k s|}||fS )a  Use Conjugate Gradient Squared iteration to solve ``Ax = b``.

    Args:
        A (ndarray, spmatrix or LinearOperator): The real or complex matrix of
            the linear system with shape ``(n, n)``.
        b (cupy.ndarray): Right hand side of the linear system with shape
            ``(n,)`` or ``(n, 1)``.
        x0 (cupy.ndarray): Starting guess for the solution.
        rtol, atol (float): Tolerance for convergence.
        maxiter (int): Maximum number of iterations.
        M (ndarray, spmatrix or LinearOperator): Preconditioner for ``A``.
            The preconditioner should approximate the inverse of ``A``.
            ``M`` must be :class:`cupy.ndarray`,
            :class:`cupyx.scipy.sparse.spmatrix` or
            :class:`cupyx.scipy.sparse.linalg.LinearOperator`.
        callback (function): User-specified function to call after each
            iteration. It is called as ``callback(xk)``, where ``xk`` is the
            current solution vector.

    Returns:
        tuple:
            It returns ``x`` (cupy.ndarray) and ``info`` (int) where ``x`` is
            the converged solution and ``info`` provides convergence
            information.

    .. seealso:: :func:`scipy.sparse.linalg.cgs`
    r   N   Tr   )r   r   r   r   r   r   r   r   r   dotcopy)r   r   r   r	   r
   r   r   r   r   r   r   r    r!   r0r$   r"   rL   r'   r#   rN   rJ   sigmar*   r)   r%   AzrI   rho_newr(   r,   r-   r-   r.   cgs   s^   
rW   c                 C  sj  t | }t| } |durtj| j|| j| jd} | jd | jd kr+td| j| jj	dvr9t
d| j| jd }|j|fksO|j|dfksOtd|| j }|du retj|f| jd	}n|j|fksv|j|dfksvtd
|| j }|du rtj| j| jd}n#t |}t|}|durtj|j||j|jd}| j|jkrtd| |||fS )a  Make a linear system Ax = b

    Args:
        A (cupy.ndarray or cupyx.scipy.sparse.spmatrix or
            cupyx.scipy.sparse.LinearOperator): sparse or dense matrix.
        M (cupy.ndarray or cupyx.scipy.sparse.spmatrix or
            cupyx.scipy.sparse.LinearOperator): preconditioner.
        x0 (cupy.ndarray): initial guess to iterative method.
        b (cupy.ndarray): right hand side.

    Returns:
        tuple:
            It returns (A, M, x, b).
            A (LinaerOperator): matrix of linear system
            M (LinearOperator): preconditioner
            x (cupy.ndarray): initial guess
            b (cupy.ndarray): right hand side.
    N)r   rmatvecr5   r   r   z"expected square matrix (shape: {})fdFDzunsupprted dtype (actual: {})zb has incompatible dimensionsr7   zx0 has incompatible dimensions)r   r5   z/matrix and preconditioner have different shapes)_make_fast_matvecr   aslinearoperatorLinearOperatorr   rX   r5   r:   r;   char	TypeErrorastyperavelr   r=   IdentityOperator)r   r   r   r   fast_matvecr    r   r-   r-   r.   r   !  s<   




r   c                   s   ddl m  ddlm t| rdrt  j	t	
d| jt	
d| jt| j jtj| jd f| jd}tj| jd f| jd}j| j|}j|} 	jjj|jjj|j	}t|tj~~~~ 	f
dd}|S d S )	Nr   )cusparsespmv      ?r   r7   c                   sT   t | }j| }j|} 	jjj|jjj|jjj
 |S N)	r   r   DnVecDescriptorcreatespMVctypesdatadescptr)r   rN   desc_xdesc_y
	_cusparsealgr*   r(   buff
cuda_dtyperc   desc_Ahandleop_ar-   r.   r   j  s   
z!_make_fast_matvec.<locals>.matvec)cupy_backends.cuda.libsrc   cupyxr   isspmatrix_csrcheck_availabilityr   get_cusparse_handle CUSPARSE_OPERATION_NON_TRANSPOSEr>   rC   r5   r   to_cuda_dtypeCUSPARSE_MV_ALG_DEFAULTr   r<   r   SpMatDescriptorrh   rg   spMV_bufferSizerj   rk   rl   int8)r   r   rN   rn   ro   	buff_sizer   r-   rp   r.   rZ   T  s.   	rZ   c                   s   t   jjdkrtjn jjdkrtjn jjdkr"tjn	 jjdkr+tj j	d t
d jt
d jt
d j fd	d
}|S )Nfdr4   Dr   re   r   g      c                   s   t j|d f jd}tj|d jj jj| jjdjj|jjd tj|d jj jj|jjdjj| jjd || fS )Nr   r7   )	r   r<   r5   _cublasCUBLAS_OP_Crj   rk   rm   CUBLAS_OP_N)rL   rK   hrD   gemvrv   moner    onezeror-   r.   rG     s   z$_make_compute_hu.<locals>.compute_hu)r   get_cublas_handler5   r]   r   sgemvdgemvcgemvzgemvr   r>   rC   )rD   rG   r-   r   r.   r?   w  s   
	r?   rf   )
__future__r   r>   r   r   
cupy._corer   	cupy.cudar   rx   r   cupyx.scipy.sparser   cupyx.scipy.sparse.linalgr   r/   rO   rW   r   rZ   r?   r-   r-   r-   r.   <module>   s*    

L
k\3#