o
    Y۷i|S                     @  s  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 ddlmZ ejdkrZdd	lmZ dd
lmZmZmZmZmZmZ ddlmZ ddlmZ n"dd	lmZ dd
lmZmZmZmZmZmZ ddlmZ ddlmZ g dZ e
dZ!e
dZ"e
dZ#e
dZ$ddlm%Z% d4ddZ&d5d d!Z'ed"G d#d$ d$ej(ee! Z)ed%G d&d' d'ej(ee! Z*G d(d) d)ee" ZG d*d+ d+ee# ZG d,d- d-ee"e#f Zed.G d/d0 d0ej(ee"e#f Z+ed1G d2d3 d3ej(ee"e#f Z,dS )6zContainer classes.    )annotationsN)AnyCallableSupportsIndexTypeVarcastoverload   )_ffi_apicore)register_object)   	   	ItemsView)IterableIteratorMappingMutableMappingMutableSequenceSequenceKeysView
ValuesView)ArrayDictListMapTKV	_DefaultT)MISSINGobjr   elem_getterCallable[[Any, int], T]lengthintidxSupportsIndex | slicereturnT | list[T]c                   sJ   t |tr||\}}} fddt|||D S t||} |S )a  Implement a pythonic __getitem__ helper.

    Parameters
    ----------
    obj
        The original object

    elem_getter
        A simple function that takes index and return a single element.

    length
        The size of the array

    idx
        The argument passed to getitem

    Returns
    -------
    result
        The element for integer indices or a :class:`list` for slices.

    c                   s   g | ]} |qS  r-   ).0ir%   r$   r-   G/home/ubuntu/vllm_env/lib/python3.10/site-packages/tvm_ffi/container.py
<listcomp>u   s    z"getitem_helper.<locals>.<listcomp>)
isinstancesliceindicesrangenormalize_index)r$   r%   r'   r)   startstopstepindexr-   r0   r1   getitem_helperW   s
   


r<   r   c              
   C  sx   zt |}W n ty } ztdt|j |d}~ww ||  k s(|| kr2td|  d| |dk r:|| 7 }|S )z*Normalize and bounds-check a Python index.z(indices must be integers or slices, not NzIndex out of range. size: z, got index r   )operatorr;   	TypeErrortype__name__
IndexError)r'   r)   r;   excr-   r-   r1   r7   {   s   r7   z	ffi.Arrayc                   @  s   e Zd ZdZd*ddZed+ddZed,ddZd-ddZd.ddZd/ddZd0ddZ	d1dd Z
d2d!d"Zd3d%d&Zd3d'd(Zd)S )4r   a<  Array container that represents a sequence of values in the FFI.

    :py:func:`tvm_ffi.convert` will map python list/tuple to this class.

    Parameters
    ----------
    input_list
        The list of values to be stored in the array.

    Examples
    --------
    .. code-block:: python

        import tvm_ffi

        a = tvm_ffi.Array([1, 2, 3])
        assert tuple(a) == (1, 2, 3)

    Notes
    -----
    For structural equality and hashing, use ``structural_equal`` and ``structural_hash`` APIs.

    See Also
    --------
    :py:func:`tvm_ffi.convert`

    
input_listIterable[T]r+   Nonec                 C     | j tjg|R   dS )z*Construct an Array from a Python sequence.N)__init_handle_by_constructor__r
   r   selfrC   r-   r-   r1   __init__      zArray.__init__r)   r   r   c                C     d S Nr-   rI   r)   r-   r-   r1   __getitem__      zArray.__getitem__r4   list[T]c                C  rL   rM   r-   rN   r-   r-   r1   rO      rP   r*   r,   c                C  s   t | }t| tj||}|S z)Return one element or a list for a slice.)lenr<   r
   ArrayGetItem)rI   r)   r'   resultr-   r-   r1   rO      s   r(   c                 C  
   t | S )z+Return the number of elements in the array.)r
   	ArraySizerI   r-   r-   r1   __len__      
zArray.__len__Iterator[T]c                 c  s&    t | }t|D ]}| | V  q	dS )z'Iterate over the elements in the array.N)rS   r6   rI   r'   r/   r-   r-   r1   __iter__   s
   zArray.__iter__strc                 C  (   |   dkrt| jd S tt| S )z,Return a string representation of the array.r   (chandle=None)__chandle__r?   r@   r^   r   __object_repr__rX   r-   r-   r1   __repr__      zArray.__repr__valueobjectboolc                 C     t | |S )z$Check if the array contains a value.)r
   ArrayContainsrI   rf   r-   r-   r1   __contains__      zArray.__contains__c                 C     t | dkS )z&Return True if the array is non-empty.r   rS   rX   r-   r-   r1   __bool__   rm   zArray.__bool__otherArray[T]c                 C     t | t| |S zConcatenate two arrays.r?   	itertoolschainrI   rq   r-   r-   r1   __add__      zArray.__add__c                 C     t | t|| S rt   ru   rx   r-   r-   r1   __radd__   rz   zArray.__radd__NrC   rD   r+   rE   r)   r   r+   r   r)   r4   r+   rQ   r)   r*   r+   r,   r+   r(   r+   r[   r+   r^   rf   rg   r+   rh   r+   rh   )rq   rD   r+   rr   )r@   
__module____qualname____doc__rJ   r   rO   rY   r]   rd   rl   rp   ry   r|   r-   r-   r-   r1   r      s    
!






r   zffi.Listc                   @  s  e Zd ZdZdEdFddZedGddZedHddZdIddZedJddZedKddZdLddZedMddZedNddZdOd dZdPd"d#Z	dQd$d%Z
dRd&d'ZdRd(d)ZdSdTd+d,ZdUd.d/ZdVd0d1ZdWd3d4ZdXd6d7ZdYd:d;ZdZd<d=Zd[d@dAZd[dBdCZdDS )\r   zEMutable list container that represents a mutable sequence in the FFI.r-   rC   rD   r+   rE   c                 C  rF   )z(Construct a List from a Python sequence.N)rG   r
   r   rH   r-   r-   r1   rJ      rK   zList.__init__r)   r   r   c                C  rL   rM   r-   rN   r-   r-   r1   rO      rP   zList.__getitem__r4   rQ   c                C  rL   rM   r-   rN   r-   r-   r1   rO      rP   r*   r,   c                C  s   t | }t| tj||S rR   )rS   r<   r
   ListGetItem)rI   r)   r'   r-   r-   r1   rO         r;   rf   c                 C  rL   rM   r-   rI   r;   rf   r-   r-   r1   __setitem__   rP   zList.__setitem__slice[int | None]c                 C  rL   rM   r-   r   r-   r-   r1   r      rP   !SupportsIndex | slice[int | None]T | Iterable[T]c                 C  s   t |trbtttt |}t| }||\}}}|dkrOtt|||}t|t|kr<t	dt| dt| t
||D ]\}	}
t| |	|
 qAdS t||}t| ||t| | dS tt| |}t| |tt| dS )z"Set one element or assign a slice.r	   z#attempt to assign sequence of size z to extended slice of size N)r3   r4   listr   r   r   rS   r5   r6   
ValueErrorzipr
   ListSetItemmaxListReplaceSlicer?   r7   )rI   r;   rf   replacementr'   r8   r9   r:   target_indicesr/   itemnormalized_indexr-   r-   r1   r      s,   

c                 C  rL   rM   r-   rI   r;   r-   r-   r1   __delitem__  rP   zList.__delitem__c                 C  rL   rM   r-   r   r-   r-   r1   r     rP   c           	      C  s   t |trBt| }||\}}}|dkr#t||}t| || dS |dkr/tt|||nt|||}|D ]}t	| | q7dS t
t| |}t	| | dS )zDelete one element or a slice.r	   r   N)r3   r4   rS   r5   r   r
   ListEraseRangereversedr6   	ListEraser7   )	rI   r;   r'   r8   r9   r:   r5   r/   r   r-   r-   r1   r     s   

	"r(   c                 C  s<   t | }|dk rtd|| }nt||}t| || dS )zInsert value before index.r   N)rS   r   minr
   
ListInsert)rI   r;   rf   r'   r-   r-   r1   insert,  s
   
zList.insertc                 C  s   t | | dS )zAppend one value to the tail.N)r
   
ListAppendrk   r-   r-   r1   append5     zList.appendc                 C     t |  dS )z"Remove all elements from the list.N)r
   	ListClearrX   r-   r-   r1   clear9     z
List.clearc                 C  r   )zReverse the list in-place.N)r
   ListReverserX   r-   r-   r1   reverse=  r   zList.reversec                 C  s4   t | }|dkrtdt||}ttt| |S )z/Remove and return item at index (default last).r   zpop from empty list)rS   rA   r7   r   r   r
   ListPop)rI   r;   r'   r   r-   r-   r1   popA  s
   
zList.popvaluesc                 C  s   t | }|| ||< dS )z!Append elements from an iterable.Nro   )rI   r   endr-   r-   r1   extendI  r   zList.extendc                 C  rV   )z*Return the number of elements in the list.)r
   ListSizerX   r-   r-   r1   rY   N  rZ   zList.__len__r[   c                 c  s0    t | }t|D ]}ttt| |V  q	dS )z&Iterate over the elements in the list.N)rS   r6   r   r   r
   r   r\   r-   r-   r1   r]   R  s
   zList.__iter__r^   c                 C  r_   )z+Return a string representation of the list.r   r`   ra   rX   r-   r-   r1   rd   X     zList.__repr__rg   rh   c                 C  ri   )z#Check if the list contains a value.)r
   ListContainsrk   r-   r-   r1   rl   ^  rm   zList.__contains__c                 C  rn   )z%Return True if the list is non-empty.r   ro   rX   r-   r-   r1   rp   b  rm   zList.__bool__rq   List[T]c                 C  rs   zConcatenate two lists.ru   rx   r-   r-   r1   ry   f  rz   zList.__add__c                 C  r{   r   ru   rx   r-   r-   r1   r|   j  rz   zList.__radd__N)r-   r}   r~   r   r   )r;   r   rf   r   r+   rE   )r;   r   rf   rD   r+   rE   )r;   r   rf   r   r+   rE   )r;   r   r+   rE   )r;   r   r+   rE   )r;   r   r+   rE   )r;   r(   rf   r   r+   rE   )rf   r   r+   rE   r+   rE   )r   )r;   r(   r+   r   )r   rD   r+   rE   r   r   r   r   r   )rq   rD   r+   r   )r@   r   r   r   rJ   r   rO   r   r   r   r   r   r   r   r   rY   r]   rd   rl   rp   ry   r|   r-   r-   r-   r1   r      s>    




	








r   c                   @  <   e Zd ZdZ	ddd	d
ZdddZdddZdddZdS )r   z!Helper class to return keys view.Nbackend_mapMap[K, V] | Dict[K, V]iter_functor_getter*Callable[..., Callable[[int], Any]] | Noner+   rE   c                 C     || _ |ptj| _d S rM   _backend_mapr
   MapForwardIterFunctor_iter_functor_getterrI   r   r   r-   r-   r1   rJ   r     zKeysView.__init__r(   c                 C  
   t | jS rM   rS   r   rX   r-   r-   r1   rY   z     
zKeysView.__len__Iterator[K]c                 c  L    t | j}| | j}t|D ]}tt|d}|V  |ds# d S qd S )Nr      )rS   r   r   r6   r   r    )rI   sizefunctor_keyr-   r-   r1   r]   }     
zKeysView.__iter__krg   rh   c                 C  s
   || j v S rM   )r   rI   r   r-   r-   r1   rl     r   zKeysView.__contains__rM   r   r   r   r   r+   rE   r   r+   r   r   rg   r+   rh   r@   r   r   r   rJ   rY   r]   rl   r-   r-   r-   r1   r   o  s    

	r   c                   @  s2   e Zd ZdZ	ddd	d
ZdddZdddZdS )r   z#Helper class to return values view.Nr   r   r   r   r+   rE   c                 C  r   rM   r   r   r-   r-   r1   rJ     r   zValuesView.__init__r(   c                 C  r   rM   r   rX   r-   r-   r1   rY     r   zValuesView.__len__Iterator[V]c                 c  r   )Nr	   r   )rS   r   r   r6   r   r!   )rI   r   r   r   rf   r-   r-   r1   r]     r   zValuesView.__iter__rM   r   r   )r+   r   )r@   r   r   r   rJ   rY   r]   r-   r-   r-   r1   r     s    
r   c                   @  r   )r   z"Helper class to return items view.Nr   r   r   r   r+   rE   c                 C  r   rM   r   r   r-   r-   r1   rJ     r   zItemsView.__init__r(   c                 C  r   rM   r   rX   r-   r-   r1   rY     r   zItemsView.__len__Iterator[tuple[K, V]]c                 c  s^    t | j}| | j}t|D ]}tt|d}tt|d}||fV  |ds, d S qd S )Nr   r	   r   )rS   r   r   r6   r   r    r!   )rI   r   r   r   r   rf   r-   r-   r1   r]     s   

zItemsView.__iter__r   rg   rh   c                 C  sD   t |trt|dkrdS |\}}| j|t}|tu rdS ||kS )Nr   F)r3   tuplerS   r   getr#   )rI   r   r   rf   actual_valuer-   r-   r1   rl     s   zItemsView.__contains__rM   r   r   )r+   r   )r   rg   r+   rh   r   r-   r-   r-   r1   r     s    


r   zffi.Mapc                   @  s   e Zd ZdZd/ddZd0ddZd1ddZd2ddZd3ddZd4ddZ	d5ddZ
d6ddZd7d d!Zed8d$d%Zed9d(d%Zd:d;d+d%Zd<d-d.Zd)S )=r   aE  Map container.

    :py:func:`tvm_ffi.convert` will map python dict to this class.

    Parameters
    ----------
    input_dict
        The dictionary of values to be stored in the map.

    Examples
    --------
    .. code-block:: python

        import tvm_ffi

        amap = tvm_ffi.Map({"a": 1, "b": 2})
        assert len(amap) == 2
        assert amap["a"] == 1
        assert amap["b"] == 2

    Notes
    -----
    For structural equality and hashing, use ``structural_equal`` and ``structural_hash`` APIs.

    See Also
    --------
    :py:func:`tvm_ffi.convert`

    
input_dictMapping[K, V]r+   rE   c                 C  sB   g }|  D ]\}}|| || q| jtjg|R   dS )z&Construct a Map from a Python mapping.N)itemsr   rG   r
   r   rI   r   list_kvsr   vr-   r-   r1   rJ     s
   
zMap.__init__r   r    r!   c                 C     t tt| |S z/Return the value for key `k` or raise KeyError.)r   r!   r
   
MapGetItemr   r-   r-   r1   rO        zMap.__getitem__rg   rh   c                 C     t | |dkS )z(Return True if the map contains key `k`.r   )r
   MapCountr   r-   r-   r1   rl     r   zMap.__contains__KeysView[K]c                 C     t | S )z(Return a dynamic view of the map's keys.r   rX   r-   r-   r1   keys     zMap.keysValuesView[V]c                 C  r   )z*Return a dynamic view of the map's values.r   rX   r-   r-   r1   r     r   z
Map.valuesItemsView[K, V]c                 C  r   )zGet the items from the map.r   rX   r-   r-   r1   r     r   z	Map.itemsr(   c                 C  rV   )z&Return the number of items in the map.)r
   MapSizerX   r-   r-   r1   rY     rZ   zMap.__len__c                 C  rn   )z$Return True if the map is non-empty.r   ro   rX   r-   r-   r1   rp   
  rm   zMap.__bool__r   c                 C     t |  S )zIterate over the map's keys.iterr   rX   r-   r-   r1   r]     rm   zMap.__iter__r   V | Nonec                 C  rL   rM   r-   rI   r   r-   r-   r1   r     rP   zMap.getdefaultV | _DefaultTc                 C  rL   rM   r-   rI   r   r   r-   r-   r1   r     rP   NV | _DefaultT | Nonec                 C     t | |}t|r|S |S )zGet an element with a default value.

        Parameters
        ----------
        key
            The attribute key.

        default
            The default object.

        Returns
        -------
        value
            The result value.

        )r
   MapGetItemOrMissingr#   same_asrI   r   r   retr-   r-   r1   r     s   
r^   c                 C  r_   )z*Return a string representation of the map.r   r`   ra   rX   r-   r-   r1   rd   .  re   zMap.__repr__)r   r   r+   rE   r   r    r+   r!   r   r+   r   r+   r   r+   r   r   r   r   r   r    r+   r   r   r    r   r   r+   r   rM   r   r    r   r   r+   r   r   )r@   r   r   r   rJ   rO   rl   r   r   r   rY   rp   r]   r   r   rd   r-   r-   r-   r1   r     s"    
#







r   zffi.Dictc                   @  s   e Zd ZdZd=d>ddZd?ddZd@ddZdAddZdBddZdCddZ	dDddZ
dEddZdFd d!ZdGd#d$ZdHd&d'ZedId*d+ZedJd.d+Zd=dKd0d+ZdLd2d3ZdMd4d5ZdNd8d9ZdOd;d<ZdS )Pr   a  Mutable dictionary container with shared reference semantics.

    Unlike :class:`Map`, ``Dict`` does NOT implement copy-on-write.
    Mutations happen directly on the underlying shared object.
    All Python references sharing the same ``Dict`` see mutations immediately.

    Parameters
    ----------
    input_dict
        The dictionary of values to be stored.

    Examples
    --------
    .. code-block:: python

        import tvm_ffi

        d = tvm_ffi.Dict({"a": 1, "b": 2})
        d["c"] = 3
        assert len(d) == 3

    Nr   Mapping[K, V] | Noner+   rE   c                 C  sJ   g }|dur|  D ]\}}|| || q
| jtjg|R   dS )z'Construct a Dict from a Python mapping.N)r   r   rG   r
   r   r   r-   r-   r1   rJ   O  s   
zDict.__init__r   r    r!   c                 C  r   r   )r   r!   r
   DictGetItemr   r-   r-   r1   rO   X  r   zDict.__getitem__r   c                 C  s   t | || dS )zSet the value for key `k`.N)r
   DictSetItem)rI   r   r   r-   r-   r1   r   \  r   zDict.__setitem__c                 C  s(   t | |dkrt|t | | dS )zDelete the entry for key `k`.r   N)r
   	DictCountKeyError	DictEraser   r-   r-   r1   r   `  s   zDict.__delitem__rg   rh   c                 C  r   )z)Return True if the dict contains key `k`.r   )r
   r  r   r-   r-   r1   rl   f  r   zDict.__contains__r(   c                 C  rV   )z'Return the number of items in the dict.)r
   DictSizerX   r-   r-   r1   rY   j  rZ   zDict.__len__c                 C  rn   )z%Return True if the dict is non-empty.r   ro   rX   r-   r-   r1   rp   n  rm   zDict.__bool__r   c                 C  r   )zIterate over the dict's keys.r   rX   r-   r-   r1   r]   r  rm   zDict.__iter__r   c                 C     t | tjS )z)Return a dynamic view of the dict's keys.)r   r
   DictForwardIterFunctorrX   r-   r-   r1   r   v  rm   z	Dict.keysr   c                 C  r  )z+Return a dynamic view of the dict's values.)r   r
   r	  rX   r-   r-   r1   r   z  rm   zDict.valuesr   c                 C  r  )zGet the items from the dict.)r   r
   r	  rX   r-   r-   r1   r   ~  rm   z
Dict.itemsr   r   c                 C  rL   rM   r-   r   r-   r-   r1   r     rP   zDict.getr   r   c                 C  rL   rM   r-   r   r-   r-   r1   r     rP   r   c                 C  r   )z$Get an element with a default value.)r
   DictGetItemOrMissingr#   r   r   r-   r-   r1   r     s   
argsc                 G  sb   t |dkrtddt |  t| |}t|r&|r"|d S t|t| | tt	|S )z;Remove and return value for key, or default if not present.r	   z&pop expected at most 2 arguments, got r   )
rS   r>   r
   r
  r#   r   r  r  r   r!   )rI   r   r  r   r-   r-   r1   r     s   

zDict.popc                 C  r   )z"Remove all elements from the dict.N)r
   	DictClearrX   r-   r-   r1   r     r   z
Dict.clearrq   r   c                 C  s   |  D ]\}}|| |< qdS )zUpdate the dict from a mapping.N)r   )rI   rq   r   r   r-   r-   r1   update  s   
zDict.updater^   c                 C  r_   )z+Return a string representation of the dict.r   r`   ra   rX   r-   r-   r1   rd     r   zDict.__repr__rM   )r   r  r+   rE   r   )r   r    r   r!   r+   rE   )r   r    r+   rE   r   r   r   r   r   r   r   r   r   r   )r   r    r  r   r+   r   r   )rq   r   r+   rE   r   )r@   r   r   r   rJ   rO   r   r   rl   rY   rp   r]   r   r   r   r   r   r   r   r  rd   r-   r-   r-   r1   r   6  s,    
	











r   )
r$   r   r%   r&   r'   r(   r)   r*   r+   r,   )r'   r(   r)   r   r+   r(   )-r   
__future__r   rv   r=   systypingr   r   r   r   r   r    r
   r   registryr   version_infocollections.abcr   ItemsViewBaser   r   r   r   r   r   r   KeysViewBaser   ValuesViewBase__all__r   r    r!   r"   r#   r<   r7   Objectr   r   r   r   r-   r-   r-   r1   <module>   sJ    	
  

$T #p"