This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git


The following commit(s) were added to refs/heads/main by this push:
     new 42e0612  Introduce opaque ptr protocol (#147)
42e0612 is described below

commit 42e0612838b231570864474ed3e1a8b1b0ebdfca
Author: Tianqi Chen <[email protected]>
AuthorDate: Thu Oct 16 13:50:10 2025 -0400

    Introduce opaque ptr protocol (#147)
    
    This PR introduces opaque ptr protocol of so DSL can pass in opaque c
    structs if needed and pass through to internla function.
---
 pyproject.toml                     |  2 +-
 python/tvm_ffi/__init__.py         |  2 +-
 python/tvm_ffi/cython/function.pxi | 15 +++++++++++++++
 tests/python/test_function.py      | 15 +++++++++++++++
 4 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/pyproject.toml b/pyproject.toml
index 0800264..fa27da1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -17,7 +17,7 @@
 
 [project]
 name = "apache-tvm-ffi"
-version = "0.1.0b19"
+version = "0.1.0b20"
 description = "tvm ffi"
 
 authors = [{ name = "TVM FFI team" }]
diff --git a/python/tvm_ffi/__init__.py b/python/tvm_ffi/__init__.py
index d2bf5a8..c97396e 100644
--- a/python/tvm_ffi/__init__.py
+++ b/python/tvm_ffi/__init__.py
@@ -18,7 +18,7 @@
 
 # order matters here so we need to skip isort here
 # isort: skip_file
-__version__ = "0.1.0b19"
+__version__ = "0.1.0b20"
 
 # HACK: try importing torch first, to avoid a potential
 # symbol conflict when both torch and tvm_ffi are imported.
diff --git a/python/tvm_ffi/cython/function.pxi 
b/python/tvm_ffi/cython/function.pxi
index 66cf4b9..46079bf 100644
--- a/python/tvm_ffi/cython/function.pxi
+++ b/python/tvm_ffi/cython/function.pxi
@@ -423,6 +423,18 @@ cdef int TVMFFIPyArgSetterCtypesVoidPtr_(
     return 0
 
 
+cdef int TVMFFIPyArgSetterFFIOpaquePtrCompatible_(
+    TVMFFIPyArgSetter* handle, TVMFFIPyCallContext* ctx,
+    PyObject* py_arg, TVMFFIAny* out
+) except -1:
+    """Setter for objects that implement the `__tvm_ffi_opaque_ptr__` 
protocol."""
+    cdef object arg = <object>py_arg
+    cdef long long long_ptr = <long long>arg.__tvm_ffi_opaque_ptr__()
+    out.type_index = kTVMFFIOpaquePtr
+    out.v_ptr = <void*>long_ptr
+    return 0
+
+
 cdef int TVMFFIPyArgSetterObjectRValueRef_(
     TVMFFIPyArgSetter* handle, TVMFFIPyCallContext* ctx,
     PyObject* py_arg, TVMFFIAny* out
@@ -675,6 +687,9 @@ cdef int TVMFFIPyArgSetterFactory_(PyObject* value, 
TVMFFIPyArgSetter* out) exce
     if isinstance(arg, ctypes.c_void_p):
         out.func = TVMFFIPyArgSetterCtypesVoidPtr_
         return 0
+    if hasattr(arg_class, "__tvm_ffi_opaque_ptr__"):
+        out.func = TVMFFIPyArgSetterFFIOpaquePtrCompatible_
+        return 0
     if callable(arg):
         out.func = TVMFFIPyArgSetterCallable_
         return 0
diff --git a/tests/python/test_function.py b/tests/python/test_function.py
index cc932f5..797e1a4 100644
--- a/tests/python/test_function.py
+++ b/tests/python/test_function.py
@@ -297,3 +297,18 @@ def test_function_subclass() -> None:
     assert isinstance(fechoed, tvm_ffi.Function)
     assert fechoed.__chandle__() == f_sub.__chandle__()
     assert fechoed(10) == 10
+
+
+def test_function_with_opaque_ptr_protocol() -> None:
+    class MyObject:
+        def __init__(self, value: Any) -> None:
+            self.value = value
+
+        def __tvm_ffi_opaque_ptr__(self) -> Any:
+            return self.value
+
+    fecho = tvm_ffi.get_global_func("testing.echo")
+    x = MyObject(10)
+    y = fecho(x)
+    assert isinstance(y, ctypes.c_void_p)
+    assert y.value == 10

Reply via email to