o
    W۷iF                     @  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Zd dlmZ d dl	m
Z
 G dd dZG dd deZe Z	 G d	d
 d
eZe Z	 ef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"ddZd!ddZdS )#    )annotationsN)	from_data)joinc                   @  s2   e Zd ZdZdd Zddd	Zd
d Zdd ZdS )AxisConcatenatorzTranslates slice objects to concatenation along an axis.

    For detailed documentation on usage, see :func:`cupy.r_`.
    This implementation is partially borrowed from NumPy's one.

    c           	      C  sZ   || }|dk r||d 7 }t t|}|}|d | ||d   |||  }||S )Nr      )listrange	transpose)	selfobjndimndmintrans1dk2defaxesk1axes r   M/home/ubuntu/vllm_env/lib/python3.10/site-packages/cupy/_indexing/generate.py_output_obj   s   

zAxisConcatenator._output_objr   Fr   c                 C  s   || _ || _|| _|| _d S N)axisr   matrixr   )r
   r   r   r   r   r   r   r   __init__"   s   
zAxisConcatenator.__init__c                   sR  | j }| j}g }g }g }t trtt ts f t D ]\\}}t|tr*tt|tr9|dkr7tdtt	|t
jv rMtj||d}	|| n)tj|d|d}	|dkrqtj|ddj}
|dkrq|
|k rq| |	|
||}	||	 ||	 qt
jg | fd	d
|D R  }|d ur|D ]}|| |||< qtjt|| jdS )Nr   z+special directives must be the first entry.)r   F)copyr   r   r   r   c                   s   g | ]} | qS r   r   ).0kkeyr   r   
<listcomp>H   s    z0AxisConcatenator.__getitem__.<locals>.<listcomp>)r   )r   r   
isinstancestrNotImplementedErrortuple	enumerateslice
ValueErrortypenumpy
ScalarTyper   arrayappendr   r   result_typeastyper   concatenater   )r
   r    r   r   objsarraysscalarsir   newobjr   final_dtyper   r   r   __getitem__(   sB   




"zAxisConcatenator.__getitem__c                 C  s   dS )Nr   r   r
   r   r   r   __len__O   s   zAxisConcatenator.__len__N)r   Fr   r   )__name__
__module____qualname____doc__r   r   r7   r9   r   r   r   r   r      s    

'r   c                         e Zd Z fddZ  ZS )CClassc                   s   t  jdddd d S )Nr      r   )r   r   superr   r8   	__class__r   r   r   U   s   zCClass.__init__r:   r;   r<   r   __classcell__r   r   rC   r   r?   S       r?   c                      r>   )RClassc                   s   t    d S r   rA   r8   rC   r   r   r   v   s   zRClass.__init__rE   r   r   rC   r   rH   t   rG   rH   c                 C  sx   t | } t| }d| }tj|f|  |d}t| D ]\}}tj||d|d| |f ||d d  ||< q|S )a  Returns an array representing the indices of a grid.

    Computes an array where the subarrays contain index values 0,1,...
    varying only along the corresponding axis.

    Args:
        dimensions: The shape of the grid.
        dtype: Data type specifier. It is int by default.

    Returns:
        ndarray:
        The array of grid indices,
        ``grid.shape = (len(dimensions),) + tuple(dimensions)``.

    Examples
    --------
    >>> grid = cupy.indices((2, 3))
    >>> grid.shape
    (2, 2, 3)
    >>> grid[0]        # row indices
    array([[0, 0, 0],
           [1, 1, 1]])
    >>> grid[1]        # column indices
    array([[0, 1, 2],
           [0, 1, 2]])

    .. seealso:: :func:`numpy.indices`

    r   dtypeNr   )r%   lencupyemptyr&   arangereshape)
dimensionsrK   Nshaperesr4   dimr   r   r   indices   s    
rV   c                  G  s   g }t | }t| D ]B\}}t|}|jdkrtd|jdkr'|tj	}t
|jt
jr4| \}|d| |jf d|| d   }|| q
t|S )a  Construct an open mesh from multiple sequences.

    This function takes N 1-D sequences and returns N outputs with N
    dimensions each, such that the shape is 1 in all but one dimension
    and the dimension with the non-unit shape value cycles through all
    N dimensions.

    Using `ix_` one can quickly construct index arrays that will index
    the cross product. ``a[cupy.ix_([1,3],[2,5])]`` returns the array
    ``[[a[1,2] a[1,5]], [a[3,2] a[3,5]]]``.

    Args:
        *args: 1-D sequences

    Returns:
        tuple of ndarrays:
        N arrays with N dimensions each, with N the number of input sequences.
        Together these arrays form an open mesh.

    Examples
    --------
    >>> a = cupy.arange(10).reshape(2, 5)
    >>> a
    array([[0, 1, 2, 3, 4],
           [5, 6, 7, 8, 9]])
    >>> ixgrid = cupy.ix_([0,1], [2,4])
    >>> ixgrid
    (array([[0],
           [1]]), array([[2, 4]]))

    .. warning::

        This function may synchronize the device.

    .. seealso:: :func:`numpy.ix_`

    r   z!Cross index must be 1 dimensionalr   rI   )rL   r&   r   asarrayr   r(   sizer/   r*   intprM   
issubdtyperK   bool_nonzerorP   r-   r%   )argsoutndr   newr   r   r   ix_   s   '



&ra   wrapCc                 C  s  t |}t | |krtd||D ]}t|tjs$tdt|qt|tr/|f| }t	
tj|ttjjkrAtdd}dg| }|du rNdn| }|dkrnt|d ddD ]}|||d   }|||< q^n|d	krtd|D ]}|||d   }|||< qwntd
tj|  } tj| d jtjd}	t||| |D ]f\}}
}}t|tjstdt|tjdstd|jt j|jtjdd}|dkrtt||k|dk rtdn|dkrt|d|d }n|dkr|| }ntd||	|
| 7 }	q|	S )a"  
    Converts a tuple of index arrays into an array of flat indices, applying
    boundary modes to the multi-index.

    Args:
        multi_index (tuple of cupy.ndarray) : A tuple of integer arrays, one
            array for each dimension.
        dims (tuple of ints): The shape of array into which the indices from
            ``multi_index`` apply.
        mode ('raise', 'wrap' or 'clip'), optional: Specifies how out-of-bounds
            indices are handled.  Can specify either one mode or a tuple of
            modes, one mode per index:

            - *'raise'* -- raise an error
            - *'wrap'* -- wrap around (default)
            - *'clip'* -- clip to the range

            In 'clip' mode, a negative index which would normally wrap will
            clip to 0 instead.
        order ('C' or 'F'), optional: Determines whether the multi-index should
            be viewed as indexing in row-major (C-style) or column-major
            (Fortran-style) order.

    Returns:
        raveled_indices (cupy.ndarray): An array of indices into the flattened
        version of an array of dimensions ``dims``.

    .. warning::

        This function may synchronize the device when ``mode == 'raise'``.

    Notes
    -----
    Note that the default `mode` (``'wrap'``) is different than in NumPy. This
    is done to avoid potential device synchronization.

    Examples
    --------
    >>> cupy.ravel_multi_index(cupy.asarray([[3,6,6],[4,5,1]]), (7,6))
    array([22, 41, 37])
    >>> cupy.ravel_multi_index(cupy.asarray([[3,6,6],[4,5,1]]), (7,6),
    ...                        order='F')
    array([31, 41, 13])
    >>> cupy.ravel_multi_index(cupy.asarray([[3,6,6],[4,5,1]]), (4,6),
    ...                        mode='clip')
    array([22, 23, 19])
    >>> cupy.ravel_multi_index(cupy.asarray([[3,6,6],[4,5,1]]), (4,4),
    ...                        mode=('clip', 'wrap'))
    array([12, 13, 13])
    >>> cupy.ravel_multi_index(cupy.asarray((3,1,4,1)), (6,7,8,9))
    array(1621)

    .. seealso:: :func:`numpy.ravel_multi_index`, :func:`unravel_index`
    z5parameter multi_index must be a sequence of length {}z-{} object cannot be interpreted as an integerzQinvalid dims: array size defined by dims is larger than the maximum possible sizer   Nrc   r@   r   Forder not understoodr   rJ   z+elements of multi_index must be cupy arrays	same_kindzgmulti_index entries could not be cast from dtype('{}') to dtype('{}') according to the rule 'same_kind'Fr   raisez"invalid entry in coordinates arraycliprb   zUnrecognized mode: {})rL   r(   formatr"   numbersIntegral	TypeErrorr)   r#   	functoolsreduceoperatormulrM   iinfoint64maxupperr   broadcast_arrayszerosrS   zipndarraycan_castrK   r/   any
logical_orrh   )multi_indexdimsmodeorderr   dsravel_stridesr4   raveled_indicesstrideidx_moder   r   r   ravel_multi_index   sp   8






r   c                 C  s   |du rdn|  }|dkrt|}n	|dkrntdt| tjds0td| jt j| dk 	 r:tdg }|D ]}|
| |  | | } q>| dk	 rVtd|dkr^t|}t|S )	a  Converts array of flat indices into a tuple of coordinate arrays.

    Args:
        indices (cupy.ndarray): An integer array whose elements are indices
            into the flattened version of an array of dimensions :obj:`dims`.
        dims (tuple of ints): The shape of the array to use for unraveling
            indices.
        order ('C' or 'F'): Determines whether the indices should be viewed as
            indexing in row-major (C-style) or column-major (Fortran-style)
            order.

    Returns:
        tuple of ndarrays:
        Each array in the tuple has the same shape as the indices array.

    Examples
    --------
    >>> cupy.unravel_index(cupy.array([22, 41, 37]), (7, 6))
    (array([3, 6, 6]), array([4, 5, 1]))
    >>> cupy.unravel_index(cupy.array([31, 41, 13]), (7, 6), order='F')
    (array([3, 6, 6]), array([4, 5, 1]))

    .. warning::

        This function may synchronize the device.

    .. seealso:: :func:`numpy.unravel_index`, :func:`ravel_multi_index`

    Nrc   rd   re   rf   zlIterator operand 0 dtype could not be cast from dtype('{}') to dtype('{}') according to the rule 'same_kind'r   zinvalid entry in index array)rt   reversedr(   rM   ry   rr   rl   ri   rK   rz   r-   r%   )rV   r}   r   unraveled_coordsrU   r   r   r   unravel_indexl  s0   

r   c                 C  s"   t j| | ft jd}||| S )a<  
    Return the indices to access (n, n) arrays, given a masking function.

    Assume `mask_func` is a function that, for a square array a of
    size ``(n, n)`` with a possible offset argument `k`, when called
    as ``mask_func(a, k)`` returns a new array with zeros in certain
    locations (functions like :func:`~cupy.triu` or :func:`~cupy.tril` do
    precisely this). Then this function returns the indices where the non-zero
    values would be located.

    Args:
        n (int): The returned indices will be valid to access arrays
            of shape (n, n).
        mask_func (callable): A function whose call signature is
            similar to that of :func:`~cupy.triu`, :func:`~tril`.  That is,
            ``mask_func(x, k)`` returns a boolean array, shaped like
            `x`.  `k` is an optional argument to the function.
        k (scalar): An optional argument which is passed through to
            `mask_func`. Functions like :func:`~cupy.triu`, :func:`~cupy.tril`
            take a second argument that is interpreted as an offset.

    Returns:
        tuple of arrays: The `n` arrays of indices corresponding to
        the locations where ``mask_func(np.ones((n, n)), k)`` is
        True.

    .. warning::

        This function may synchronize the device.

    .. seealso:: :func:`numpy.mask_indices`
    rJ   )rM   onesint8r\   )n	mask_funcr   ar   r   r   mask_indices  s   !r   c                   s4   t j| ||td t fddt j jtdD S )a  Returns the indices of the lower triangular matrix.
    Here, the first group of elements contains row coordinates
    of all indices and the second group of elements
    contains column coordinates.

    Parameters
    ----------
    n : int
        The row dimension of the arrays for which the returned
        indices will be valid.
    k : int, optional
        Diagonal above which to zero elements. `k = 0`
        (the default) is the main diagonal, `k < 0` is
        below it and `k > 0` is above.
    m : int, optional
        The column dimension of the arrays for which the
        returned arrays will be valid. By default, `m = n`.

    Returns
    -------
    y : tuple of ndarrays
        The indices for the triangle. The returned tuple
        contains two arrays, each with the indices along
        one dimension of the array.

    See Also
    --------
    numpy.tril_indices

    r   rK   c                 3  "    | ]}t | j  V  qd S r   rM   broadcast_torS   r   indstri_r   r   	<genexpr>      ztril_indices.<locals>.<genexpr>rJ   rM   triboolr%   rV   rS   intr   r   mr   r   r   tril_indices  s    r   c                 C  ,   | j dkr	tdt| jd || jd dS )a6  Returns the indices for the lower-triangle of arr.

    Parameters
    ----------
    arr : cupy.ndarray
          The indices are valid for square arrays
          whose dimensions are the same as arr.
    k : int, optional
        Diagonal offset.

    See Also
    --------
    numpy.tril_indices_from

    r@   input array must be 2-dr   r   r   )r   r(   r   rS   arrr   r   r   r   tril_indices_from  s   
r   c                   s:   t j| ||d td  t fddt j jtdD S )a  Returns the indices of the upper triangular matrix.
    Here, the first group of elements contains row coordinates
    of all indices and the second group of elements
    contains column coordinates.

    Parameters
    ----------
    n : int
        The size of the arrays for which the returned indices will
        be valid.
    k : int, optional
        Refers to the diagonal offset. By default, `k = 0` i.e.
        the main dialogal. The positive value of `k`
        denotes the diagonals above the main diagonal, while the negative
        value includes the diagonals below the main diagonal.
    m : int, optional
        The column dimension of the arrays for which the
        returned arrays will be valid. By default, `m = n`.

    Returns
    -------
    y : tuple of ndarrays
        The indices for the triangle. The returned tuple
        contains two arrays, each with the indices along
        one dimension of the array.

    See Also
    --------
    numpy.triu_indices

    r   r   c                 3  r   r   r   r   r   r   r   r   3  r   ztriu_indices.<locals>.<genexpr>rJ   r   r   r   r   r   triu_indices  s   !r   c                 C  r   )a  Returns indices for the upper-triangle of arr.

    Parameters
    ----------
    arr : cupy.ndarray
          The indices are valid for square arrays.
    k : int, optional
        Diagonal offset (see 'triu_indices` for details).

    Returns
    -------
    triu_indices_from : tuple of ndarrays
        Indices for the upper-triangle of `arr`.

    See Also
    --------
    numpy.triu_indices_from

    r@   r   r   r   r   )r   r(   r   rS   r   r   r   r   triu_indices_from7  s   
r   )rb   rc   )rc   )r   )r   N)
__future__r   rm   rj   ro   r*   rM   cupy._creationr   cupy._manipulationr   r   r?   c_rH   r_r   rV   ra   r   r   r   r   r   r   r   r   r   r   r   <module>   s0   C)
7
t
=
+
&
'