o
    W۷iT                     @  s   d dl m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dZ
d-d	d
Zd-ddZd-ddZd.ddZd.ddZd.ddZd.ddZejjddddZd/ddZd0dd Zddd!d"d#Zd1d$d%Zd2d'd(Zd-d)d*Zd.d+d,ZdS )3    )annotationsN)_routines_math)_fusion_thread_local)internalFc                 C  N   t  r|r
td|du rtj}ntj}t j|| |||dS | ||||S )a  Returns the sum of an array along given axes.

    Args:
        a (cupy.ndarray): Array to take sum.
        axis (int or sequence of ints): Axes along which the sum is taken.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.
        keepdims (bool): If ``True``, the specified axes are remained as axes
            of length one.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.sum`

    z3cupy.sum does not support `keepdims` in fusion yet.Naxisdtypeout)r   	is_fusingNotImplementedError_mathsum_auto_dtype_sum_keep_dtypecall_reductionsumar   r	   r
   keepdimsfunc r   H/home/ubuntu/vllm_env/lib/python3.10/site-packages/cupy/_math/sumprod.pyr         
r   c                 C  r   )a  Returns the product of an array along given axes.

    Args:
        a (cupy.ndarray): Array to take product.
        axis (int or sequence of ints): Axes along which the product is taken.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.
        keepdims (bool): If ``True``, the specified axes are remained as axes
            of length one.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.prod`

    z4cupy.prod does not support `keepdims` in fusion yet.Nr   )r   r   r   r   _prod_auto_dtype_prod_keep_dtyper   prodr   r   r   r   r   -   r   r   c                 C  sd   t  r)|r
td| jjdv rtj}n|du rtj}ntj}t j	|| |||dS t
| ||||S )a  Returns the sum of an array along given axes treating Not a Numbers
    (NaNs) as zero.

    Args:
        a (cupy.ndarray): Array to take sum.
        axis (int or sequence of ints): Axes along which the sum is taken.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.
        keepdims (bool): If ``True``, the specified axes are remained as axes
            of length one.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.nansum`

    z6cupy.nansum does not support `keepdims` in fusion yet.FDNr   )r   r   r   r	   charr   _nansum_complex_dtype_nansum_auto_dtype_nansum_keep_dtyper   _nansumr   r   r   r   nansumM   s   
r"   c                 C  sP   t  r|r
td|du rtj}ntj}t j|| |||dS t| ||||S )a  Returns the product of an array along given axes treating Not a Numbers
    (NaNs) as zero.

    Args:
        a (cupy.ndarray): Array to take product.
        axis (int or sequence of ints): Axes along which the product is taken.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.
        keepdims (bool): If ``True``, the specified axes are remained as axes
            of length one.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.nanprod`

    z7cupy.nanprod does not support `keepdims` in fusion yet.Nr   )r   r   r   r   _nanprod_auto_dtype_nanprod_keep_dtyper   _nanprodr   r   r   r   nanprodp   s   
r&   c                 C     t | |t jj||S )a  Returns the cumulative sum of an array along a given axis.

    Args:
        a (cupy.ndarray): Input array.
        axis (int): Axis along which the cumulative sum is taken. If it is not
            specified, the input is flattened.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.cumsum`

    )r   	scan_corescan_opSCAN_SUMr   r   r	   r
   r   r   r   cumsum      r,   c                 C  r'   )a  Returns the cumulative product of an array along a given axis.

    Args:
        a (cupy.ndarray): Input array.
        axis (int): Axis along which the cumulative product is taken. If it is
            not specified, the input is flattened.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.cumprod`

    )r   r(   r)   	SCAN_PRODr+   r   r   r   cumprod   r-   r/   c                 C     t | d|d} t| |||dS )a  Returns the cumulative sum of an array along a given axis treating Not a
    Numbers (NaNs) as zero.

    Args:
        a (cupy.ndarray): Input array.
        axis (int): Axis along which the cumulative sum is taken. If it is not
            specified, the input is flattened.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.nancumsum`
    r   r
   r   )_replace_nanr,   r+   r   r   r   	nancumsum      r3   c                 C  r0   )a  Returns the cumulative product of an array along a given axis treating
    Not a Numbers (NaNs) as one.

    Args:
        a (cupy.ndarray): Input array.
        axis (int): Axis along which the cumulative product is taken. If it is
            not specified, the input is flattened.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.nancumprod`
       r1   r   )r2   r/   r+   r   r   r   
nancumprod   r4   r6   z
T a, T valzT outz(if (a == a) {out = a;} else {out = val;}cupy_replace_nanc                 C  s.   |d u s
| j |j krt| }t| || |S N)r	   cupy
empty_like_replace_nan_kernel)r   valr
   r   r   r   r2      s   
r2   r5   c                 C  sz  |dkr| S |dk rt dt| t| } | j}t||}g }|durFt|}|jdkrAt| j}d||< t	|t
|}|| ||  |durot|}|jdkrjt| j}d||< t	|t
|}|| t|dkr{t||} tdg| }tdg| }	tdd||< tdd|	|< t
|}t
|	}	| jtjkrtjntj}
t|D ]}|
| | | |	 } q| S )a1  Calculate the n-th discrete difference along the given axis.

    Args:
        a (cupy.ndarray): Input array.
        n (int): The number of times values are differenced. If zero, the input
            is returned as-is.
        axis (int): The axis along which the difference is taken, default is
            the last axis.
        prepend (int, float, cupy.ndarray): Value to prepend to ``a``.
        append (int, float, cupy.ndarray): Value to append to ``a``.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.diff`
    r   z#order must be non-negative but got Nr5   r=   )
ValueErrorreprr9   
asanyarrayndimr   _normalize_axis_indexlistshapebroadcast_totupleappendlenconcatenateslicer	   numpybool_	not_equalsubtractrange)r   nr   prependrG   ndcombinedrD   slice1slice2op_r   r   r   diff   sJ   










rX   )r   
edge_orderc                G  st  t | } | j}tj||dd}t|}t|}|dkr"dg| }nm|dkr4t |d dkr4|| }n[||krt|}t|D ]I\}	}
t |
dkrLq@t |
dkrWtdt|
| j	||	  krftdt
|
jt
jrt|
t
j}
t |
}||d k r|d }|||	< q@ntd|d	krtd
g }tdg| }tdg| }tdg| }tdg| }| j}t
|t
jrnt
|t
jr| t
j} t
j}t||D ]\}}| j	| |d k rtdt j| |d}t |dk}tdd||< tdd||< tdd||< td	d||< |r)| t| | t|  d|  |t|< nU|dd }|dd }|| }| ||  }|| ||  }|||  }dg| }d||< t| |_	 |_	|_	|| t|  || t|   || t|   |t|< |dkrd||< d||< d||< |r|n|d }| t| | t|  | |t|< d||< d||< d||< |r|n|d }| t| | t|  | |t|< nd||< d||< d||< d	||< |rd| }d| }d| }n$|d }|d }|| }d| |  ||  }|||  }| ||  }|| t|  || t|   || t|   |t|< d||< d||< d||< d||< |rRd| }d| }d| }n#|d }|d }|| }|||  }| ||  }d| | ||  }|| t|  || t|   || t|   |t|< || td||< td||< td||< td||< q|dkr|d S |S )a  Return the gradient of an N-dimensional array.

    The gradient is computed using second order accurate central differences
    in the interior points and either first or second order accurate one-sides
    (forward or backwards) differences at the boundaries.
    The returned gradient hence has the same shape as the input array.

    Args:
        f (cupy.ndarray): An N-dimensional array containing samples of a scalar
            function.
        varargs (list of scalar or array, optional): Spacing between f values.
            Default unitary spacing for all dimensions. Spacing can be
            specified using:

            1. single scalar to specify a sample distance for all dimensions.
            2. N scalars to specify a constant sample distance for each
               dimension. i.e. `dx`, `dy`, `dz`, ...
            3. N arrays to specify the coordinates of the values along each
               dimension of F. The length of the array must match the size of
               the corresponding dimension
            4. Any combination of N scalars/arrays with the meaning of 2. and
               3.

            If `axis` is given, the number of varargs must equal the number of
            axes. Default: 1.
        edge_order ({1, 2}, optional): The gradient is calculated using N-th
            order accurate differences at the boundaries. Default: 1.
        axis (None or int or tuple of ints, optional): The gradient is
            calculated only along the given axis or axes. The default
            (axis = None) is to calculate the gradient for all the axes of the
            input array. axis may be negative, in which case it counts from the
            last to the first axis.

    Returns:
        gradient (cupy.ndarray or list of cupy.ndarray): A set of ndarrays
        (or a single ndarray if there is only one dimension) corresponding
        to the derivatives of f with respect to each dimension. Each
        derivative has the same shape as f.

    .. seealso:: :func:`numpy.gradient`
    F)	sort_axesr         ?r5   z&distances must be either scalars or 1dzGwhen 1d, distances must match the length of the corresponding dimensionzinvalid number of arguments   z)'edge_order' greater than 2 not supportedNzlShape of array too small to calculate a numerical gradient, at least (edge_order + 1) elements are required.r	   r=          @g      g      g      ?g       g      ?)r9   r@   rA   r   _normalize_axis_indicesrH   rC   	enumerater>   rD   rK   
issubdtyper	   integerastypefloat64rX   all	TypeErrorrJ   inexactzipr:   rF   rG   )fr   rY   varargsrA   axeslen_axesrP   dxi	distancesdiffxoutvalsrT   rU   slice3slice4otypeax_dxr
   uniform_spacingdx1dx2dx_sumr   bcrD   dx_0dx_nr   r   r   gradient,  s   
*




$&



r   c                 C  sb  t | tjs
td|  } | j}|du r%|du r%| dd | dd  S |du r,d}nt |tjs6tdtj||ddsBtd	| }t|}|du rQd}nt |tjs[td
tj||ddsgtd| }t|}tt| d d}tj	|| | | jd}|dkr||d|< |dkr|||| d< t
| dd | dd ||||   |S )a  
    Calculates the difference between consecutive elements of an array.

    Args:
        arr (cupy.ndarray): Input array.
        to_end (cupy.ndarray, optional): Numbers to append at the end
            of the returned differences.
        to_begin (cupy.ndarray, optional): Numbers to prepend at the
            beginning of the returned differences.

    Returns:
        cupy.ndarray: New array consisting differences among succeeding
        elements.

    .. seealso:: :func:`numpy.ediff1d`
    z$`arr` should be of type cupy.ndarrayNr5   r=   r   z)`to_begin` should be of type cupy.ndarray	same_kind)castingzSdtype of `to_begin` must be compatible with input `arr` under the `same_kind` rule.z'`to_end` should be of type cupy.ndarrayzQdtype of `to_end` must be compatible with input `arr` under the `same_kind` rule.r]   )
isinstancer9   ndarrayrh   ravelr	   can_castrH   maxemptyrN   )arrto_endto_begin	dtype_reql_beginl_endl_diffresultr   r   r   ediff1d  s<   *r   r[   c                 C  s  t | tjs
td|du r|}n,t |tjstd|jdkr7t|}dg| j }|jd ||< ||}nt||d}| j}tdg| }tdg| }tdd||< tdd||< || t	| | t	|   d }	z|	
|}
W |
S  ty   tj|	|}
Y |
S w )	a  
    Integrate along the given axis using the composite trapezoidal rule.
    Integrate `y` (`x`) along the given axis.

    Args:
        y (cupy.ndarray): Input array to integrate.
        x (cupy.ndarray): Sample points over which to integrate. If None equal
            spacing `dx` is assumed.
        dx (float): Spacing between sample points, used if `x` is None, default
            is 1.
        axis (int): The axis along which the integral is taken, default is
            the last axis.

    Returns:
        cupy.ndarray: Definite integral as approximated by the trapezoidal
        rule.

    .. seealso:: :func:`numpy.trapezoid`
    z"`y` should be of type cupy.ndarrayNz"`x` should be of type cupy.ndarrayr5   r   )r   r=   r_   )r   r9   r   rh   rA   rX   rD   reshaperJ   rF   r   r>   addreduce)yxro   r   drD   rR   rT   rU   productretr   r   r   	trapezoidH  s2   
 r   c                 C  s   t dt t| ||||S )NzPlease use `prod` instead.)warningswarnDeprecationWarningr   )r   r   r	   r
   r   r   r   r   r   y  s   r   c                 C  s   t dt t| |||S )NzPlease use `cumprod` instead.)r   r   r   r/   r+   r   r   r   
cumproduct~  s   r   )NNNF)NNNr8   )r5   r=   NN)NN)Nr[   r=   )
__future__r   r   rK   r9   
cupy._corer   r   r   r   r   r   r"   r&   r,   r/   r3   r6   _core_kernelElementwiseKernelr;   r2   rX   r   r   r   r   r   r   r   r   r   <module>   s6    

 
 
#
!




A 
W
F
1