o
    ic'                     @  s  d Z ddlm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 ddlmZ dZe
d	ed
ZdAdBddZ		dCdDddZedEdd ZedFdGd#d ZdFdHd$d ZdId&d'ZdJd)d*ZdKd,d-ZdAdLd0d1ZdMd6d7ZdNd;d<ZdOd>d?Zg d@ZdS )Pz.FFI registry to register function and objects.    )annotationsN)AnyCallableLiteralSequenceTypeVaroverload   )core)TypeInfoF_T)boundtype_key
str | NonereturnCallable[[_T], _T]c                   s\   ddd t trd fdd	}|S d fd
d}du r!|S t tr*|S td)a  Register object type.

    Parameters
    ----------
    type_key
        The type key of the node. It requires ``type_key`` to be registered already
        on the C++ side. If not specified, the class name will be used.

    Examples
    --------
    The following code registers MyObject using type key "test.MyObject", if the
    type key is already registered on the C++ side.

    .. code-block:: python

      @tvm_ffi.register_object("test.MyObject")
      class MyObject(Object):
          pass

    clsr   object_namestrr   c                 S  sP   t |}|du rtr| S td| t || }t| |d t| d| | S )z+Register the object type with the FFI core.Nz"Cannot find object type index for )type_cls	type_info__tvm_ffi_type_info__)r
   _object_type_key_to_index_SKIP_UNKNOWN_OBJECTS
ValueError_register_object_by_index_add_class_attrssetattr)r   r   
type_indexinfo r    M/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/tvm_ffi/registry.py	_register9   s   
z"register_object.<locals>._registerc                   s
    | S Nr    r   r"   r   r    r!   _decorator_with_nameG   s   
z-register_object.<locals>._decorator_with_namec                   s    | | j S r#   )__name__r$   )r"   r    r!   _decorator_defaultL   s   z+register_object.<locals>._decorator_defaultNz(type_key must be a string, type, or None)r   r   r   r   r   r   )r   r   r   r   )
isinstancer   type	TypeError)r   r&   r(   r    r%   r!   register_object#   s   


r,   	func_namestr | Callable[..., Any]fCallable[..., Any] | Noneoverrideboolr   c                   sH   t  r	 }|j t tstdd	 fdd}|dur"||S |S )
a  Register global function.

    Parameters
    ----------
    func_name
        The function name

    f
        The function to be registered.

    override
        Whether override existing entry.

    Returns
    -------
    fregister
        Register function if f is not specified.

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

        import tvm_ffi


        # we can use decorator to register a function
        @tvm_ffi.register_global_func("mytest.echo")
        def echo(x):
            return x


        # After registering, we can get the function by its name
        f = tvm_ffi.get_global_func("mytest.echo")
        assert f(1) == 1

        # we can also directly register a function
        tvm_ffi.register_global_func("mytest.add_one", lambda x: x + 1)
        f = tvm_ffi.get_global_func("mytest.add_one")
        assert f(1) == 2

    See Also
    --------
    :py:func:`tvm_ffi.get_global_func`
    :py:func:`tvm_ffi.remove_global_func`

    zexpect string function namemyfCallable[..., Any]r   r   c                   s   t  | S )z/Register the global function with the FFI core.)r
   _register_global_func)r3   r-   r1   r    r!   register   s   z&register_global_func.<locals>.registerN)r3   r4   r   r   )callabler'   r)   r   r   )r-   r/   r1   r7   r    r6   r!   register_global_funcV   s   3
r9   namer   allow_missingLiteral[True]core.Function | Nonec                 C     d S r#   r    r:   r;   r    r    r!   get_global_func      r@   Literal[False]core.Functionc                 C  r>   r#   r    r?   r    r    r!   r@      rA   c                 C  s   t | |S )am  Get a global function by name.

    Parameters
    ----------
    name
        The name of the global function

    allow_missing
        Whether allow missing function or raise an error.

    Returns
    -------
    func
        The function to be returned, ``None`` if function is missing.

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

        import tvm_ffi


        @tvm_ffi.register_global_func("demo.echo")
        def echo(x):
            return x


        f = tvm_ffi.get_global_func("demo.echo")
        assert f(123) == 123

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

    )r
   _get_global_funcr?   r    r    r!   r@      s   $	list[str]c                    s(   t d   d}  fddt| D S )zxGet list of global functions registered.

    Returns
    -------
    names
       List of global functions names.

    z"ffi.FunctionListGlobalNamesFunctorc                   s   g | ]} |qS r    r    ).0iname_functorr    r!   
<listcomp>   s    z*list_global_func_names.<locals>.<listcomp>)r@   range)	num_namesr    rI   r!   list_global_func_names   s   
	rN   Nonec                 C  s   t d|  dS )aa  Remove a global function by name.

    Parameters
    ----------
    name
        The name of the global function.

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

        import tvm_ffi


        @tvm_ffi.register_global_func("my.temp")
        def temp():
            return 42


        assert tvm_ffi.get_global_func("my.temp", allow_missing=True) is not None
        tvm_ffi.remove_global_func("my.temp")
        assert tvm_ffi.get_global_func("my.temp", allow_missing=True) is None

    See Also
    --------
    :py:func:`tvm_ffi.register_global_func`
    :py:func:`tvm_ffi.get_global_func`

    zffi.FunctionRemoveGlobalNr@   r:   r    r    r!   remove_global_func   s   rR   dict[str, Any]c                 C  s   t td| p	dS )a  Get metadata (including type schema) for a global function.

    Parameters
    ----------
    name
        The name of the global function.

    Returns
    -------
    metadata
        A dictionary containing function metadata. The ``type_schema`` field
        encodes the callable signature.

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

        import tvm_ffi

        meta = tvm_ffi.get_global_func_metadata("testing.add_one")
        print(meta)

    See Also
    --------
    :py:func:`tvm_ffi.get_global_func`
        Retrieve a callable for an existing global function.
    :py:func:`tvm_ffi.register_global_func`
        Register a Python callable as a global FFI function.

    zffi.GetGlobalFuncMetadataz{})jsonloadsr@   rQ   r    r    r!   get_global_func_metadata   s   rV   	namespacetarget_module_namec                 C  s   |r|n| }|  dr| dd }n| }tj| }t D ]*}| |s$q|t|d d }|ddkr6qt|}t|d| t||| qdS )a  Initialize register ffi api  functions into a given module.

    Parameters
    ----------
    namespace
       The namespace of the source registry

    target_module_name
       The target module name if different from namespace

    Examples
    --------
    A typical usage pattern is to create a _ffi_api.py file to register
    the functions under a given module. The following
    code populates all registered global functions
    prefixed with ``mypackage.`` into the current module,
    then we can call the function through ``_ffi_api.func_name(*args)``
    which will call into the registered global function "mypackage.func_name".

    .. code-block:: python

        # _ffi_api.py
        import tvm_ffi

        tvm_ffi.init_ffi_api("mypackage", __name__)

    ztvm.   Nr	   .rF   r'   )
startswithsysmodulesrN   lenfindr@   r   )rW   rX   prefixtarget_moduler:   fnamer/   r    r    r!   init_ffi_api  s   



rc   r   r*   r   r   c                 C  s   |j D ]}|j}t| |st| |||  qd}|jD ]}|j}|dkr)d}d}t| |s7t| |||  qd| jvrV|rJt| dt| d | S t	| t
jsVt| dt | S )NF__ffi_init____c_ffi_init__T__init__)fieldsr:   hasattrr   as_propertymethodsas_callable__dict__getattr
issubclassr
   PyNativeObject__init__invalid)r   r   fieldr:   
has_c_initmethodr    r    r!   r   K  s*   




r   selfargskwargsc                 O  s   t d)Nz5The __init__ method of this class is not implemented.)RuntimeError)rt   ru   rv   r    r    r!   rp   `  s   rp   Sequence[str]c                   C  s
   t d S )zGet the list of valid type keys registered to TVM-FFI.

    Returns
    -------
    type_keys
        List of valid type keys.

    zffi.GetRegisteredTypeKeysrP   r    r    r    r!   get_registered_type_keysd  s   
	ry   )r@   rV   ry   rc   rN   r9   r,   rR   r#   )r   r   r   r   )NF)r-   r.   r/   r0   r1   r2   r   r   )r:   r   r;   r<   r   r=   )F)r:   r   r;   rB   r   rC   )r:   r   r;   r2   r   r=   )r   rE   )r:   r   r   rO   )r:   r   r   rS   )rW   r   rX   r   r   rO   )r   r*   r   r   r   r*   )rt   r   ru   r   rv   r   r   rO   )r   rx   )__doc__
__future__r   rT   r\   typingr   r   r   r   r   r    r
   r   r   r*   r   r,   r9   r@   rN   rR   rV   rc   r   rp   ry   __all__r    r    r    r!   <module>   s4    5C
'

!"
2

