o
    پi)                     @   sr  d Z ddlmZ ddlZddlZddlZddlmZm	Z	m
Z
mZmZmZ ddlmZmZmZmZ ddlmZmZ edkr>eneZz3ed	krHe ejd
kr`ddlmZmZmZmZ ddlmZ nddl mZmZmZmZ ddl mZ W n ey   ddl!mZmZmZmZ ddl!mZ Y nw dddZ"dd Z#de"ddfddZ$dd Z%G dd deZdd Z&dddZ'dS )zRuntime NDArray api    )absolute_importN   )_LIB
check_callc_arraystring_types	_FFI_MODEc_str)
DECORDTypeDECORDContextDECORDArrayDECORDArrayHandle)TypeCodedecord_shape_index_tcythonctypes)   r   )_set_class_ndarray_reg_extension_make_array_from_dlpack)NDArrayBasec                 C   s@   t | tr|  d } | tjvrtd|  tj|  } t| |S )a~  Construct a DECORD context with given device type and id.

    Parameters
    ----------
    dev_type: int or str
        The device type mask or name of the device.

    dev_id : int, optional
        The integer device id

    Returns
    -------
    ctx: DECORDContext
        The corresponding context.

    Examples
    --------
    Context can be used to create reflection of context by
    string representation of the device type.

    .. code-block:: python

      assert decord.context("cpu", 1) == decord.cpu(1)
      assert decord.context("gpu", 0) == decord.gpu(0)
      assert decord.context("cuda", 0) == decord.gpu(0)
    r   zUnknown device type %s)
isinstancer   splitr   STR2MASK
ValueError)dev_typedev_id r   G/home/ubuntu/.local/lib/python3.10/site-packages/decord/_ffi/ndarray.pycontext   s   



r    c                 C   sp   | }|j d s	J t }tt|j}|jtj|_||_d|_	t
t|jj|_|j|_tdd|_||fS )z:Return a DECORDArray representation of a numpy array.
    C_CONTIGUOUSNr   r   )flagsr   r   r   shaper   data_asc_void_pdatastridesr
   npdtypenamendimr    ctx)np_datar&   arrr#   r   r   r   numpyasarrayA   s   r/   float32c                 C   sn   t t| } tt| }t }t|}tt	| |t|j
t|jt|j|j|jt| t|dS )aX  Create an empty array given shape and device

    Parameters
    ----------
    shape : tuple of int
        The shape of the array

    dtype : type or str
        The data type of the array.

    ctx : DECORDContext
        The context of the array

    Returns
    -------
    arr : decord.nd.NDArray
        The array decord supported.
    F)r   r   r   c_intlenr   r
   r   r   DECORDArrayAlloc	type_codebitslanesdevice_type	device_idbyrefr   )r#   r)   r,   r+   handler   r   r   emptyR   s   




r;   c                 C   s   t | S )a  Produce an array from a DLPack tensor without memory copy.
    Retrieves the underlying DLPack tensor's pointer to create an array from the
    data. Removes the original DLPack tensor's destructor as now the array is
    responsible for destruction.

    Parameters
    ----------
    dltensor : DLPack tensor
        Input DLManagedTensor, can only be consumed once.

    Returns
    -------
    arr: decord.nd.NDArray
        The array view of the tensor data.
    )r   )dltensorr   r   r   from_dlpackt   s   r=   c                   @   s   e Zd ZdZedd Zedd Zedd Zedd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )r   z,A simple Device/CPU Array object in runtime.c                    s    t  fddt jjjD S )zShape of this arrayc                 3   s    | ]
} j jj| V  qd S N)r:   contentsr#   ).0iselfr   r   	<genexpr>   s    z$NDArrayBase.shape.<locals>.<genexpr>)tupleranger:   r?   r+   rB   r   rB   r   r#      s    zNDArrayBase.shapec                 C   s   t | jjjS )zType of this array)strr:   r?   r)   rB   r   r   r   r)      s   zNDArrayBase.dtypec                 C   s
   | j jjS zcontext of this array)r:   r?   r,   rB   r   r   r   r,      s   
zNDArrayBase.ctxc                 C   s   | j S rH   )r,   rB   r   r   r   r       s   zNDArrayBase.contextc                 C   s   t | jt jjS r>   )r   castr:   r%   valuerB   r   r   r   __hash__   s   zNDArrayBase.__hash__c                 C   s
   |  |S r>   )same_asrC   otherr   r   r   __eq__   s   
zNDArrayBase.__eq__c                 C   s   |  | S r>   )rO   rM   r   r   r   __ne__      zNDArrayBase.__ne__c                 C   s   t |tsdS |  | kS )zCheck object identity equality

        Parameters
        ----------
        other : object
            The other object to compare to

        Returns
        -------
        same : bool
            Whether other is same as self.
        F)r   r   rK   rM   r   r   r   rL      s   
zNDArrayBase.same_asc                 C   s   t |tr|jdus|jdurtdt |tr'|j| jur%||  dS dS t |tj	tj
fr7| | dS tdtt| )zSet ndarray valueNz'Array only support set from numpy arrayztype %s not supported)r   slicestartstopr   r   r:   copytor(   ndarraygenericcopyfrom	TypeErrorrG   type)rC   in_slicerJ   r   r   r   __setitem__   s   



zNDArrayBase.__setitem__c              	   C   s  t |tr||  | S t |tjs,z
tj|| jd}W n   tddtt	|  t
| j}| j| j}}|jdkrJ||jf }d|_t|}|j|krXtd|j|tj||d}|jd sfJ |jtj}t|j|jj }tt| j|| | S )a  Perform a synchronized copy from the array.

        Parameters
        ----------
        source_array : array_like
            The data source we should like to copy from.

        Returns
        -------
        arr : NDArray
            Reference to self.
        r)   z!array must be an array_like data,ztype %s is not supportedr   z8array shape do not match the shape of NDArray {0} vs {1}r!   )r   r   rU   r(   rV   arrayr)   rY   rG   rZ   r
   r#   r6   r   formatascontiguousarrayr"   r   r$   r%   c_size_tsizeitemsizer   r   DECORDArrayCopyFromBytesr:   )rC   source_arraytr#   r)   r&   nbytesr   r   r   rX      s4   




zNDArrayBase.copyfromc                 C   s$   d | j| j}||   7 }|S )Nz <decord.NDArray shape={0}, {1}>
)r_   r#   r    asnumpy__repr__)rC   resr   r   r   ri      s   zNDArrayBase.__repr__c                 C   s   t |  S r>   )rG   rh   rB   r   r   r   __str__   rQ   zNDArrayBase.__str__c                 C   s   t | j}| j| j}}|jdkr||jf }d|_t|}tj||d}|jd s,J |j	tj
}t|j|jj }tt| j|| |S )zConvert this array to numpy array

        Returns
        -------
        np_arr : numpy.ndarray
            The corresponding numpy array.
        r   r]   r!   )r
   r)   r#   r6   rG   r(   r;   r"   r   r$   r%   ra   rb   rc   r   r   DECORDArrayCopyToBytesr:   )rC   rf   r#   r)   np_arrr&   rg   r   r   r   rh      s   

zNDArrayBase.asnumpyc                 C   sR   t |trt| j| j|}t |trtt| j	|j	d |S t
dtt| )zCopy array to target

        Parameters
        ----------
        target : NDArray
            The target array to be copied, must have same shape as this array.
        NzUnsupported target type %s)r   r   r;   r#   r)   r   r   r   DECORDArrayCopyFromTor:   r   rG   rZ   )rC   targetr   r   r   rU   
  s   


zNDArrayBase.copytoN)__name__
__module____qualname____doc__propertyr#   r)   r,   r    rK   rO   rP   rL   r\   rX   ri   rk   rh   rU   r   r   r   r   r      s(    



(r   c                 C   s   t t| t| dS )zFree c++ extension type handle

    Parameters
    ----------
    handle : ctypes.c_void_p
        The handle to the extension type.

    type_code : int
         The tyoe code
    N)r   r   DECORDExtTypeFreer   r1   )r:   r4   r   r   r   free_extension_handle  s   rv   c                 C   s&   |r| j tjk rtdt| | | S )a  Register a extension class to DECORD.

    After the class is registered, the class will be able
    to directly pass as Function argument generated by DECORD.

    Parameters
    ----------
    cls : class
        The class object to be registered as extension.

    Note
    ----
    The registered class is requires one property: _decord_handle and a class attribute _decord_tcode.

    - ```_decord_handle``` returns integer represents the address of the handle.
    - ```_decord_tcode``` gives integer represents type code of the class.

    Returns
    -------
    cls : class
        The class being registered.

    fcreate : function, optional
        The creation function to create a class object given handle value.

    Example
    -------
    The following code registers user defined class
    MyTensor to be DLTensor compatible.

    .. code-block:: python

       @decord.register_extension
       class MyTensor(object):
           _decord_tcode = decord.TypeCode.ARRAY_HANDLE

           def __init__(self):
               self.handle = _LIB.NewDLTensor()

           @property
           def _decord_handle(self):
               return self.handle.value
    z>Cannot register create when extension tcode is same as buildin)_decord_tcoder   	EXT_BEGINr   r   )clsfcreater   r   r   register_extension)  s   ,
r{   )r   r>   )(rs   
__future__r   sysr   numpyr(   baser   r   r   r   r   r	   runtime_ctypesr
   r   r   r   r   r   RuntimeErrorImportErrorIMPORT_EXCEPTversion_info	_cy3.corer   r   r   r   r   _NDArrayBase	_cy2.core_ctypes.ndarrayr    r/   r;   r=   rv   r{   r   r   r   r   <module>   s<    

#" 