From a239f0100da28c248798c8f44086c55339747870 Mon Sep 17 00:00:00 2001 From: tqchen Date: Sat, 30 Aug 2025 08:29:06 -0400 Subject: [PATCH] [FFI][ABI] ABI Updates to for future metadata and complex ordering This PR updates the ABI to enable potential future need for getting metadata from a dynamically loaded module. Orders the current static object into simple objects that have C ABI and more complex one that may need c++. These items changes ABI to be future compact before we freeze. --- ffi/include/tvm/ffi/c_api.h | 23 +++++++++++-------- ffi/include/tvm/ffi/extra/module.h | 14 +++++++++++ ffi/pyproject.toml | 2 +- ffi/python/tvm_ffi/cython/base.pxi | 9 ++++---- ffi/scripts/run_tests.sh | 4 +++- ffi/src/ffi/extra/module.cc | 18 +++++++++++++++ .../main/java/org/apache/tvm/TypeIndex.java | 8 +++---- web/src/ctypes.ts | 8 +++---- 8 files changed, 62 insertions(+), 24 deletions(-) diff --git a/ffi/include/tvm/ffi/c_api.h b/ffi/include/tvm/ffi/c_api.h index b1107c4a0cad..f099898b158d 100644 --- a/ffi/include/tvm/ffi/c_api.h +++ b/ffi/include/tvm/ffi/c_api.h @@ -126,19 +126,22 @@ typedef enum { kTVMFFIError = 67, /*! \brief Function object. */ kTVMFFIFunction = 68, - /*! \brief Array object. */ - kTVMFFIArray = 69, - /*! \brief Map object. */ - kTVMFFIMap = 70, /*! * \brief Shape object, layout = { TVMFFIObject, { const int64_t*, size_t }, ... } */ - kTVMFFIShape = 71, + kTVMFFIShape = 69, /*! * \brief NDArray object, layout = { TVMFFIObject, DLTensor, ... } */ - kTVMFFINDArray = 72, - /*! \brief Runtime module object. */ + kTVMFFINDArray = 70, + /*! \brief Array object. */ + kTVMFFIArray = 71, + //---------------------------------------------------------------- + // more complex objects + //---------------------------------------------------------------- + /*! \brief Map object. */ + kTVMFFIMap = 72, + /*! \brief Runtime dynamic loaded module object. */ kTVMFFIModule = 73, kTVMFFIStaticObjectEnd, // [Section] Dynamic Boxed: [kTVMFFIDynObjectBegin, +oo) @@ -763,11 +766,11 @@ typedef struct TVMFFITypeInfo { * * \param name The name of the function. * \param f The function to be registered. - * \param override Whether allow override already registered function. + * \param allow_override Whether allow override already registered function. * \return 0 when success, nonzero when failure happens */ TVM_FFI_DLL int TVMFFIFunctionSetGlobal(const TVMFFIByteArray* name, TVMFFIObjectHandle f, - int override); + int allow_override); /*! * \brief Register the function to runtime's global table with method info. @@ -780,7 +783,7 @@ TVM_FFI_DLL int TVMFFIFunctionSetGlobal(const TVMFFIByteArray* name, TVMFFIObjec * \return 0 when success, nonzero when failure happens */ TVM_FFI_DLL int TVMFFIFunctionSetGlobalFromMethodInfo(const TVMFFIMethodInfo* method_info, - int override); + int allow_override); /*! * \brief Register type field information for runtime reflection. diff --git a/ffi/include/tvm/ffi/extra/module.h b/ffi/include/tvm/ffi/extra/module.h index f220c582a91f..bc7dff159cda 100644 --- a/ffi/include/tvm/ffi/extra/module.h +++ b/ffi/include/tvm/ffi/extra/module.h @@ -68,6 +68,12 @@ class TVM_FFI_EXTRA_CXX_API ModuleObj : public Object { * \return True if the module implements the function, false otherwise. */ virtual bool ImplementsFunction(const String& name) { return GetFunction(name).defined(); } + /*! + * \brief Get the metadata of the function, if available. + * \param name The name of the function. + * \return The metadata stored in json string format. + */ + virtual Optional GetFunctionMetadata(const String& name) { return std::nullopt; } /*! * \brief Write the current module to file with given format (for further compilation). * @@ -121,6 +127,12 @@ class TVM_FFI_EXTRA_CXX_API ModuleObj : public Object { * \return True if the module implements the function, false otherwise. */ bool ImplementsFunction(const String& name, bool query_imports); + /*! + * \brief Get the function metadata of the function if available. + * \param name The name of the function. + * \return The function metadata of the function in json format. + */ + Optional GetFunctionMetadata(const String& name, bool query_imports); /*! * \brief Get the imports of the module. * \return The imports of the module. @@ -215,6 +227,8 @@ namespace symbol { constexpr const char* tvm_ffi_library_ctx = "__tvm_ffi_library_ctx"; /*! \brief Global variable to store binary data alongside a library module. */ constexpr const char* tvm_ffi_library_bin = "__tvm_ffi_library_bin"; +/*! \brief Optional metadata prefix of a symbol. */ +constexpr const char* tvm_ffi_metadata_prefix = "__tvm_ffi_metadata_"; /*! \brief Default entry function of a library module. */ constexpr const char* tvm_ffi_main = "__tvm_ffi_main__"; } // namespace symbol diff --git a/ffi/pyproject.toml b/ffi/pyproject.toml index 60fdb27b5a43..3efa1d9455a1 100644 --- a/ffi/pyproject.toml +++ b/ffi/pyproject.toml @@ -17,7 +17,7 @@ [project] name = "apache-tvm-ffi" -version = "0.1.0a2" +version = "0.1.0a3" description = "tvm ffi" authors = [{ name = "TVM FFI team" }] diff --git a/ffi/python/tvm_ffi/cython/base.pxi b/ffi/python/tvm_ffi/cython/base.pxi index 4caecc1f9657..14b3d97f5260 100644 --- a/ffi/python/tvm_ffi/cython/base.pxi +++ b/ffi/python/tvm_ffi/cython/base.pxi @@ -48,12 +48,13 @@ cdef extern from "tvm/ffi/c_api.h": kTVMFFIBytes = 66 kTVMFFIError = 67 kTVMFFIFunction = 68 - kTVMFFIArray = 69 - kTVMFFIMap = 70 - kTVMFFIShape = 71 - kTVMFFINDArray = 72 + kTVMFFIShape = 69 + kTVMFFINDArray = 70 + kTVMFFIArray = 71 + kTVMFFIMap = 72 kTVMFFIModule = 73 + ctypedef void* TVMFFIObjectHandle ctypedef struct DLDataType: diff --git a/ffi/scripts/run_tests.sh b/ffi/scripts/run_tests.sh index 118162569cb9..27795cc74512 100755 --- a/ffi/scripts/run_tests.sh +++ b/ffi/scripts/run_tests.sh @@ -17,7 +17,9 @@ # under the License. set -euxo pipefail -BUILD_TYPE=Release +BUILD_TYPE=RelWithDebugInfo + +rm -rf build/CMakeCache.txt cmake -G Ninja -S . -B build -DTVM_FFI_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_COMPILER_LAUNCHER=ccache diff --git a/ffi/src/ffi/extra/module.cc b/ffi/src/ffi/extra/module.cc index d8ec77f98c97..9450917bc5f2 100644 --- a/ffi/src/ffi/extra/module.cc +++ b/ffi/src/ffi/extra/module.cc @@ -44,6 +44,20 @@ Optional ModuleObj::GetFunction(const String& name, bool query_imports return std::nullopt; } +Optional ModuleObj::GetFunctionMetadata(const String& name, bool query_imports) { + if (auto opt_metadata = this->GetFunctionMetadata(name)) { + return opt_metadata; + } + if (query_imports) { + for (const Any& import : imports_) { + if (auto opt_metadata = import.cast()->GetFunctionMetadata(name, query_imports)) { + return *opt_metadata; + } + } + } + return std::nullopt; +} + void ModuleObj::ImportModule(const Module& other) { std::unordered_set visited{other.operator->()}; std::vector stack{other.operator->()}; @@ -115,6 +129,10 @@ TVM_FFI_STATIC_INIT_BLOCK({ [](Module mod, String name, bool query_imports) { return mod->ImplementsFunction(name, query_imports); }) + .def_method("ffi.ModuleGetFunctionMetadata", + [](Module mod, String name, bool query_imports) { + return mod->GetFunctionMetadata(name, query_imports); + }) .def_method("ffi.ModuleGetFunction", [](Module mod, String name, bool query_imports) { return mod->GetFunction(name, query_imports); diff --git a/jvm/core/src/main/java/org/apache/tvm/TypeIndex.java b/jvm/core/src/main/java/org/apache/tvm/TypeIndex.java index 97169bb6c58c..7689cc58ed63 100644 --- a/jvm/core/src/main/java/org/apache/tvm/TypeIndex.java +++ b/jvm/core/src/main/java/org/apache/tvm/TypeIndex.java @@ -36,9 +36,9 @@ public class TypeIndex { public static final int kTVMFFIBytes = 66; public static final int kTVMFFIError = 67; public static final int kTVMFFIFunction = 68; - public static final int kTVMFFIArray = 69; - public static final int kTVMFFIMap = 70; - public static final int kTVMFFIShape = 71; - public static final int kTVMFFINDArray = 72; + public static final int kTVMFFIShape = 70; + public static final int kTVMFFINDArray = 71; + public static final int kTVMFFIArray = 72; + public static final int kTVMFFIMap = 73; public static final int kTVMFFIModule = 73; } diff --git a/web/src/ctypes.ts b/web/src/ctypes.ts index 41d848a22886..d2ecf4b944b0 100644 --- a/web/src/ctypes.ts +++ b/web/src/ctypes.ts @@ -97,16 +97,16 @@ export const enum TypeIndex { kTVMFFIFunction = 68, /*! \brief Array object. */ kTVMFFIArray = 69, - /*! \brief Map object. */ - kTVMFFIMap = 70, /*! * \brief Shape object, layout = { TVMFFIObject, { const int64_t*, size_t }, ... } */ - kTVMFFIShape = 71, + kTVMFFIShape = 70, /*! * \brief NDArray object, layout = { TVMFFIObject, DLTensor, ... } */ - kTVMFFINDArray = 72, + kTVMFFINDArray = 71, + /*! \brief Map object. */ + kTVMFFIMap = 72, /*! \brief Runtime module object. */ kTVMFFIModule = 73, }