Skip to content

Commit a08fa6e

Browse files
committed
[FFI][REFACTOR] Streamline Object Declare Macros (apache#18289)
1 parent 4ffbc88 commit a08fa6e

File tree

16 files changed

+93
-131
lines changed

16 files changed

+93
-131
lines changed

docs/guides/cpp_guide.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,7 @@ class MyIntPairObj : public tvm::ffi::Object {
105105

106106
// Required: declare type information
107107
// to register a dynamic type index through the system
108-
static constexpr const char* _type_key = "example.MyIntPair";
109-
// This macro registers the class with the FFI system to set up the right type index
110-
TVM_FFI_DECLARE_FINAL_OBJECT_INFO(MyIntPairObj, tvm::ffi::Object);
108+
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("example.MyIntPair", MyIntPairObj, tvm::ffi::Object);
111109
};
112110

113111
void ExampleObjectPtr() {
@@ -138,7 +136,7 @@ class MyIntPair : public tvm::ffi::ObjectRef {
138136
139137
// Required: define object reference methods
140138
// This macro provides the necessary methods for ObjectRef functionality
141-
TVM_FFI_DEFINE_OBJECT_REF_METHODS(MyIntPair, tvm::ffi::ObjectRef, MyIntPairObj);
139+
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(MyIntPair, tvm::ffi::ObjectRef, MyIntPairObj);
142140
};
143141
144142
void ExampleObjectRef() {

docs/guides/python_guide.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,7 @@ public:
188188
TestIntPairObj(int64_t a, int64_t b) : a(a), b(b) {}
189189

190190
// Required: declare type information
191-
static constexpr const char* _type_key = "testing.TestIntPair";
192-
TVM_FFI_DECLARE_FINAL_OBJECT_INFO(TestIntPairObj, tvm::ffi::Object);
191+
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("testing.TestIntPair", TestIntPairObj, tvm::ffi::Object);
193192
};
194193

195194
// Step 2: Define the reference wrapper (user-facing interface)
@@ -201,7 +200,7 @@ public:
201200
}
202201

203202
// Required: define object reference methods
204-
TVM_FFI_DEFINE_OBJECT_REF_METHODS(TestIntPair, tvm::ffi::ObjectRef, TestIntPairObj);
203+
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(TestIntPair, tvm::ffi::ObjectRef, TestIntPairObj);
205204
};
206205

207206
TVM_FFI_STATIC_INIT_BLOCK({

include/tvm/ffi/container/array.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,8 @@ class ArrayObj : public Object, public details::InplaceArrayBase<ArrayObj, TVMFF
157157

158158
/// \cond Doxygen_Suppress
159159
static constexpr const int32_t _type_index = TypeIndex::kTVMFFIArray;
160-
static constexpr const char* _type_key = StaticTypeKey::kTVMFFIArray;
161160
static const constexpr bool _type_final = true;
162-
TVM_FFI_DECLARE_STATIC_OBJECT_INFO(ArrayObj, Object);
161+
TVM_FFI_DECLARE_OBJECT_INFO_STATIC(StaticTypeKey::kTVMFFIArray, ArrayObj, Object);
163162
/// \endcond
164163

165164
private:

include/tvm/ffi/container/map.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,8 @@ class MapObj : public Object {
7373

7474
/// \cond Doxygen_Suppress
7575
static constexpr const int32_t _type_index = TypeIndex::kTVMFFIMap;
76-
static constexpr const char* _type_key = StaticTypeKey::kTVMFFIMap;
7776
static const constexpr bool _type_final = true;
78-
TVM_FFI_DECLARE_STATIC_OBJECT_INFO(MapObj, Object);
77+
TVM_FFI_DECLARE_OBJECT_INFO_STATIC(StaticTypeKey::kTVMFFIMap, MapObj, Object);
7978
/// \endcond
8079

8180
/*!

include/tvm/ffi/container/shape.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ class ShapeObj : public Object, public TVMFFIShapeCell {
5353

5454
/// \cond Doxygen_Suppress
5555
static constexpr const uint32_t _type_index = TypeIndex::kTVMFFIShape;
56-
static constexpr const char* _type_key = StaticTypeKey::kTVMFFIShape;
57-
TVM_FFI_DECLARE_STATIC_OBJECT_INFO(ShapeObj, Object);
56+
TVM_FFI_DECLARE_OBJECT_INFO_STATIC(StaticTypeKey::kTVMFFIShape, ShapeObj, Object);
5857
/// \endcond
5958
};
6059

@@ -212,7 +211,7 @@ class Shape : public ObjectRef {
212211
int64_t Product() const { return get()->Product(); }
213212

214213
/// \cond Doxygen_Suppress
215-
TVM_FFI_DEFINE_NOTNULLABLE_OBJECT_REF_METHODS(Shape, ObjectRef, ShapeObj);
214+
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Shape, ObjectRef, ShapeObj);
216215
/// \endcond
217216

218217
private:

include/tvm/ffi/container/tensor.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ class TensorObj : public Object, public DLTensor {
121121
public:
122122
/// \cond Doxygen_Suppress
123123
static constexpr const uint32_t _type_index = TypeIndex::kTVMFFITensor;
124-
static constexpr const char* _type_key = StaticTypeKey::kTVMFFITensor;
125-
TVM_FFI_DECLARE_STATIC_OBJECT_INFO(TensorObj, Object);
124+
TVM_FFI_DECLARE_OBJECT_INFO_STATIC(StaticTypeKey::kTVMFFITensor, TensorObj, Object);
126125
/// \endcond
127126

128127
/*!
@@ -363,7 +362,7 @@ class Tensor : public ObjectRef {
363362
DLManagedTensorVersioned* ToDLPackVersioned() const { return get_mutable()->ToDLPackVersioned(); }
364363

365364
/// \cond Doxygen_Suppress
366-
TVM_FFI_DEFINE_OBJECT_REF_METHODS(Tensor, ObjectRef, TensorObj);
365+
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(Tensor, ObjectRef, TensorObj);
367366
/// \endcond
368367

369368
protected:

include/tvm/ffi/error.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ class ErrorObj : public Object, public TVMFFIErrorCell {
8787
public:
8888
/// \cond Doxygen_Suppress
8989
static constexpr const int32_t _type_index = TypeIndex::kTVMFFIError;
90-
static constexpr const char* _type_key = "ffi.Error";
91-
TVM_FFI_DECLARE_STATIC_OBJECT_INFO(ErrorObj, Object);
90+
TVM_FFI_DECLARE_OBJECT_INFO_STATIC("ffi.Error", ErrorObj, Object);
9291
/// \endcond
9392
};
9493

@@ -196,7 +195,7 @@ class Error : public ObjectRef, public std::exception {
196195
}
197196

198197
/// \cond Doxygen_Suppress
199-
TVM_FFI_DEFINE_NOTNULLABLE_OBJECT_REF_METHODS(Error, ObjectRef, ErrorObj);
198+
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Error, ObjectRef, ErrorObj);
200199
/// \endcond
201200
};
202201

include/tvm/ffi/extra/module.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ class TVM_FFI_EXTRA_CXX_API ModuleObj : public Object {
146146

147147
/// \cond Doxygen_Suppress
148148
static constexpr const int32_t _type_index = TypeIndex::kTVMFFIModule;
149-
static constexpr const char* _type_key = StaticTypeKey::kTVMFFIModule;
149+
static constexpr const bool _type_mutable = true;
150150
static const constexpr bool _type_final = true;
151-
TVM_FFI_DECLARE_STATIC_OBJECT_INFO(ModuleObj, Object);
151+
TVM_FFI_DECLARE_OBJECT_INFO_STATIC(StaticTypeKey::kTVMFFIModule, ModuleObj, Object);
152152
/// \endcond
153153

154154
protected:
@@ -234,7 +234,7 @@ class Module : public ObjectRef {
234234
const ffi::TypedFunction<void(String, void*)>& callback);
235235

236236
/// \cond Doxygen_Suppress
237-
TVM_FFI_DEFINE_MUTABLE_NOTNULLABLE_OBJECT_REF_METHODS(Module, ObjectRef, ModuleObj);
237+
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Module, ObjectRef, ModuleObj);
238238
/// \endcond
239239
};
240240

include/tvm/ffi/function.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ class FunctionObj : public Object, public TVMFFIFunctionCell {
116116
}
117117
/// \cond Doxygen_Suppress
118118
static constexpr const uint32_t _type_index = TypeIndex::kTVMFFIFunction;
119-
static constexpr const char* _type_key = StaticTypeKey::kTVMFFIFunction;
120-
TVM_FFI_DECLARE_STATIC_OBJECT_INFO(FunctionObj, Object);
119+
TVM_FFI_DECLARE_OBJECT_INFO_STATIC(StaticTypeKey::kTVMFFIFunction, FunctionObj, Object);
121120
/// \endcond
122121

123122
protected:
@@ -594,7 +593,7 @@ class Function : public ObjectRef {
594593
TVM_FFI_INLINE bool operator!=(std::nullptr_t) const { return data_ != nullptr; }
595594

596595
/// \cond Doxygen_Suppress
597-
TVM_FFI_DEFINE_OBJECT_REF_METHODS(Function, ObjectRef, FunctionObj);
596+
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(Function, ObjectRef, FunctionObj);
598597
/// \endcond
599598

600599
class Registry;

include/tvm/ffi/object.h

Lines changed: 48 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ TVM_FFI_INLINE bool IsObjectInstance(int32_t object_type_index);
154154
* The unique string identifier of the type.
155155
* - _type_final:
156156
* Whether the type is terminal type(there is no subclass of the type in the object system).
157-
* This field is automatically set by macro TVM_DECLARE_FINAL_OBJECT_INFO
157+
* This field is automatically set by macro TVM_FFI_DECLARE_OBJECT_INFO_FINAL
158158
* It is still OK to sub-class a terminal object type T and construct it using make_object.
159159
* But IsInstance check will only show that the object type is T(instead of the sub-class).
160160
* - _type_mutable:
@@ -177,8 +177,8 @@ TVM_FFI_INLINE bool IsObjectInstance(int32_t object_type_index);
177177
* Recommendation: set to false for optimal runtime speed if we know exact number of children.
178178
*
179179
* Two macros are used to declare helper functions in the object:
180-
* - Use TVM_FFI_DECLARE_BASE_OBJECT_INFO for object classes that can be sub-classed.
181-
* - Use TVM_FFI_DECLARE_FINAL_OBJECT_INFO for object classes that cannot be sub-classed.
180+
* - Use TVM_FFI_DECLARE_OBJECT_INFO for object classes that can be sub-classed.
181+
* - Use TVM_FFI_DECLARE_OBJECT_INFO_FINAL for object classes that cannot be sub-classed.
182182
*
183183
* New objects can be created using make_object function.
184184
* Which will automatically populate the type_index and deleter of the object.
@@ -276,7 +276,7 @@ class Object {
276276
/*! \brief The structural equality and hash kind of the type */
277277
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindUnsupported;
278278
// The following functions are provided by macro
279-
// TVM_FFI_DECLARE_BASE_OBJECT_INFO and TVM_DECLARE_FINAL_OBJECT_INFO
279+
// TVM_FFI_DECLARE_OBJECT_INFO and TVM_FFI_DECLARE_OBJECT_INFO_FINAL
280280
/*!
281281
* \brief Get the runtime allocated type index of the type
282282
* \note Getting this information may need dynamic calls into a global table.
@@ -885,20 +885,24 @@ struct ObjectPtrEqual {
885885
/// \endcond
886886

887887
/*!
888-
* \brief Helper macro to declare a object that comes with static type index.
888+
* \brief Helper macro to declare object information with static type index.
889+
*
890+
* \param TypeKey The type key of the current type.
889891
* \param TypeName The name of the current type.
890892
* \param ParentType The name of the ParentType
891893
*/
892-
#define TVM_FFI_DECLARE_STATIC_OBJECT_INFO(TypeName, ParentType) \
893-
static int32_t RuntimeTypeIndex() { return TypeName::_type_index; } \
894+
#define TVM_FFI_DECLARE_OBJECT_INFO_STATIC(TypeKey, TypeName, ParentType) \
895+
static constexpr const char* _type_key = TypeKey; \
896+
static int32_t RuntimeTypeIndex() { return TypeName::_type_index; } \
894897
TVM_FFI_REGISTER_STATIC_TYPE_INFO(TypeName, ParentType)
895898

896899
/*!
897-
* \brief helper macro to declare a base object type that can be inherited.
900+
* \brief Helper macro to declare object information with type key already defined in class.
901+
*
898902
* \param TypeName The name of the current type.
899903
* \param ParentType The name of the ParentType
900904
*/
901-
#define TVM_FFI_DECLARE_BASE_OBJECT_INFO(TypeName, ParentType) \
905+
#define TVM_FFI_DECLARE_OBJECT_INFO_PREDEFINED_TYPE_KEY(TypeName, ParentType) \
902906
static constexpr int32_t _type_depth = ParentType::_type_depth + 1; \
903907
static int32_t _GetOrAllocRuntimeTypeIndex() { \
904908
static_assert(!ParentType::_type_final, "ParentType marked as final"); \
@@ -916,14 +920,27 @@ struct ObjectPtrEqual {
916920
static inline int32_t _type_index = _GetOrAllocRuntimeTypeIndex()
917921

918922
/*!
919-
* \brief helper macro to declare type information in a final class.
923+
* \brief Helper macro to declare object information with dynamic type index.
924+
*
925+
* \param TypeKey The type key of the current type.
920926
* \param TypeName The name of the current type.
921927
* \param ParentType The name of the ParentType
922928
*/
923-
#define TVM_FFI_DECLARE_FINAL_OBJECT_INFO(TypeName, ParentType) \
924-
static const constexpr int _type_child_slots [[maybe_unused]] = 0; \
925-
static const constexpr bool _type_final [[maybe_unused]] = true; \
926-
TVM_FFI_DECLARE_BASE_OBJECT_INFO(TypeName, ParentType)
929+
#define TVM_FFI_DECLARE_OBJECT_INFO(TypeKey, TypeName, ParentType) \
930+
static constexpr const char* _type_key = TypeKey; \
931+
TVM_FFI_DECLARE_OBJECT_INFO_PREDEFINED_TYPE_KEY(TypeName, ParentType)
932+
933+
/*!
934+
* \brief Helper macro to declare object information with dynamic type index and is final.
935+
*
936+
* \param TypeKey The type key of the current type.
937+
* \param TypeName The name of the current type.
938+
* \param ParentType The name of the ParentType
939+
*/
940+
#define TVM_FFI_DECLARE_OBJECT_INFO_FINAL(TypeKey, TypeName, ParentType) \
941+
static const constexpr int _type_child_slots [[maybe_unused]] = 0; \
942+
static const constexpr bool _type_final [[maybe_unused]] = true; \
943+
TVM_FFI_DECLARE_OBJECT_INFO(TypeKey, TypeName, ParentType)
927944

928945
/*!
929946
* \brief Define object reference methods.
@@ -935,13 +952,15 @@ struct ObjectPtrEqual {
935952
* \note This macro also defines the default constructor that puts the ObjectRef
936953
* in undefined state initially.
937954
*/
938-
#define TVM_FFI_DEFINE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
939-
TypeName() = default; \
940-
explicit TypeName(::tvm::ffi::ObjectPtr<ObjectName> n) : ParentType(n) {} \
941-
explicit TypeName(::tvm::ffi::UnsafeInit tag) : ParentType(tag) {} \
942-
TVM_FFI_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName) \
943-
const ObjectName* operator->() const { return static_cast<const ObjectName*>(data_.get()); } \
944-
const ObjectName* get() const { return operator->(); } \
955+
#define TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(TypeName, ParentType, ObjectName) \
956+
TypeName() = default; \
957+
explicit TypeName(::tvm::ffi::ObjectPtr<ObjectName> n) : ParentType(n) {} \
958+
explicit TypeName(::tvm::ffi::UnsafeInit tag) : ParentType(tag) {} \
959+
TVM_FFI_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName) \
960+
using __PtrType = std::conditional_t<ObjectName::_type_mutable, ObjectName*, const ObjectName*>; \
961+
__PtrType operator->() const { return static_cast<__PtrType>(data_.get()); } \
962+
__PtrType get() const { return static_cast<__PtrType>(data_.get()); } \
963+
static constexpr bool _type_is_nullable = true; \
945964
using ContainerType = ObjectName
946965

947966
/*!
@@ -951,46 +970,17 @@ struct ObjectPtrEqual {
951970
* \param ParentType The parent type of the objectref
952971
* \param ObjectName The type name of the object.
953972
*/
954-
#define TVM_FFI_DEFINE_NOTNULLABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
955-
explicit TypeName(::tvm::ffi::UnsafeInit tag) : ParentType(tag) {} \
956-
TVM_FFI_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName) \
957-
const ObjectName* operator->() const { return static_cast<const ObjectName*>(data_.get()); } \
958-
const ObjectName* get() const { return operator->(); } \
959-
static constexpr bool _type_is_nullable = false; \
960-
using ContainerType = ObjectName
961-
962-
/*!
963-
* \brief Define object reference methods of whose content is mutable.
964-
* \param TypeName The object type name
965-
* \param ParentType The parent type of the objectref
966-
* \param ObjectName The type name of the object.
967-
* \note We recommend making objects immutable when possible.
968-
* This macro is only reserved for objects that stores runtime states.
969-
*/
970-
#define TVM_FFI_DEFINE_MUTABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
971-
TypeName() = default; \
972-
explicit TypeName(::tvm::ffi::UnsafeInit tag) : ParentType(tag) {} \
973-
TVM_FFI_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName) \
974-
explicit TypeName(::tvm::ffi::ObjectPtr<ObjectName> n) : ParentType(n) {} \
975-
ObjectName* operator->() const { return static_cast<ObjectName*>(data_.get()); } \
976-
using ContainerType = ObjectName
977-
978-
/*!
979-
* \brief Define object reference methods that is both not nullable and mutable.
980-
*
981-
* \param TypeName The object type name
982-
* \param ParentType The parent type of the objectref
983-
* \param ObjectName The type name of the object.
984-
*/
985-
#define TVM_FFI_DEFINE_MUTABLE_NOTNULLABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
986-
explicit TypeName(::tvm::ffi::UnsafeInit tag) : ParentType(tag) {} \
987-
TVM_FFI_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName) \
988-
ObjectName* operator->() const { return static_cast<ObjectName*>(data_.get()); } \
989-
ObjectName* get() const { return operator->(); } \
990-
static constexpr bool _type_is_nullable = false; \
973+
#define TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(TypeName, ParentType, ObjectName) \
974+
explicit TypeName(::tvm::ffi::UnsafeInit tag) : ParentType(tag) {} \
975+
TVM_FFI_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName) \
976+
using __PtrType = std::conditional_t<ObjectName::_type_mutable, ObjectName*, const ObjectName*>; \
977+
__PtrType operator->() const { return static_cast<__PtrType>(data_.get()); } \
978+
__PtrType get() const { return static_cast<__PtrType>(data_.get()); } \
979+
static constexpr bool _type_is_nullable = false; \
991980
using ContainerType = ObjectName
992981

993982
namespace details {
983+
994984
template <typename TargetType>
995985
TVM_FFI_INLINE bool IsObjectInstance(int32_t object_type_index) {
996986
static_assert(std::is_base_of_v<Object, TargetType>);

0 commit comments

Comments
 (0)