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