23 #ifndef TVM_RUNTIME_OBJECT_H_
24 #define TVM_RUNTIME_OBJECT_H_
27 #include <tvm/runtime/logging.h>
30 #include <type_traits>
39 #ifndef TVM_OBJECT_ATOMIC_REF_COUNTER
40 #define TVM_OBJECT_ATOMIC_REF_COUNTER 1
43 #if TVM_OBJECT_ATOMIC_REF_COUNTER
185 std::string
GetTypeKey()
const {
return TypeIndex2Key(type_index_); }
195 template <
typename TargetType>
196 inline bool IsInstance()
const;
201 inline bool unique()
const;
221 #if TVM_OBJECT_ATOMIC_REF_COUNTER
227 static constexpr
const char* _type_key =
"runtime.Object";
233 static constexpr
bool _type_final =
false;
234 static constexpr uint32_t _type_child_slots = 0;
235 static constexpr
bool _type_child_slots_can_overflow =
true;
237 static constexpr
bool _type_has_method_visit_attrs =
true;
238 static constexpr
bool _type_has_method_sequal_reduce =
false;
239 static constexpr
bool _type_has_method_shash_reduce =
false;
266 uint32_t type_index_{0};
274 FDeleter deleter_ =
nullptr;
278 "RefCounter ABI check.");
298 uint32_t parent_tindex, uint32_t type_child_slots,
299 bool type_child_slots_can_overflow);
303 inline void IncRef();
308 inline void DecRef();
315 inline int use_count()
const;
321 bool DerivedFrom(uint32_t parent_tindex)
const;
328 friend class ObjectInternal;
343 template <
typename ObjectRefType,
typename ObjectType>
344 inline ObjectRefType
GetRef(
const ObjectType* ptr);
354 template <
typename SubRef,
typename BaseRef>
355 inline SubRef
Downcast(BaseRef ref);
362 template <
typename T>
379 template <
typename U>
382 static_assert(std::is_base_of<T, U>::value,
383 "can only assign of child class ObjectPtr to parent");
390 : data_(other.data_) {
391 other.data_ =
nullptr;
397 template <
typename Y>
399 : data_(other.data_) {
400 static_assert(std::is_base_of<T, Y>::value,
401 "can only assign of child class ObjectPtr to parent");
402 other.data_ =
nullptr;
411 std::swap(data_, other.data_);
416 T*
get()
const {
return static_cast<T*
>(data_); }
452 explicit operator bool()
const {
return get() !=
nullptr; }
455 if (data_ !=
nullptr) {
461 int use_count()
const {
return data_ !=
nullptr ? data_->use_count() : 0; }
463 bool unique()
const {
return data_ !=
nullptr && data_->use_count() == 1; }
469 bool operator==(std::nullptr_t
null)
const {
return data_ ==
nullptr; }
471 bool operator!=(std::nullptr_t
null)
const {
return data_ !=
nullptr; }
481 if (data !=
nullptr) {
490 static ObjectPtr<T> MoveFromRValueRefArg(
Object** ref) {
509 template <
typename ObjectRefType,
typename ObjType>
510 friend ObjectRefType
GetRef(
const ObjType* ptr);
511 template <
typename BaseType,
typename ObjType>
516 template <
typename T>
575 template <
typename ObjectType,
typename = std::enable_if_t<std::is_base_of_v<Object, ObjectType>>>
576 inline const ObjectType*
as()
const;
595 template <
typename ObjectRefType,
596 typename = std::enable_if_t<std::is_base_of_v<ObjectRef, ObjectRefType>>>
615 template <
typename T>
617 return T(std::move(ref.
data_));
631 template <
typename ObjectType>
640 template <
typename SubRef,
typename BaseRef>
641 friend SubRef
Downcast(BaseRef ref);
652 template <
typename BaseType,
typename ObjectType>
659 template <
typename T>
661 return std::hash<Object*>()(a.
get());
669 template <
typename T>
680 #define TVM_DECLARE_BASE_OBJECT_INFO(TypeName, ParentType) \
681 static_assert(!ParentType::_type_final, "ParentObj marked as final"); \
682 static uint32_t RuntimeTypeIndex() { \
683 static_assert(TypeName::_type_child_slots == 0 || ParentType::_type_child_slots == 0 || \
684 TypeName::_type_child_slots < ParentType::_type_child_slots, \
685 "Need to set _type_child_slots when parent specifies it."); \
686 if (TypeName::_type_index != ::tvm::runtime::TypeIndex::kDynamic) { \
687 return TypeName::_type_index; \
689 return _GetOrAllocRuntimeTypeIndex(); \
691 static uint32_t _GetOrAllocRuntimeTypeIndex() { \
692 static uint32_t tindex = Object::GetOrAllocRuntimeTypeIndex( \
693 TypeName::_type_key, TypeName::_type_index, ParentType::_GetOrAllocRuntimeTypeIndex(), \
694 TypeName::_type_child_slots, TypeName::_type_child_slots_can_overflow); \
703 #define TVM_DECLARE_FINAL_OBJECT_INFO(TypeName, ParentType) \
704 static const constexpr bool _type_final = true; \
705 static const constexpr int _type_child_slots = 0; \
706 TVM_DECLARE_BASE_OBJECT_INFO(TypeName, ParentType)
709 #if defined(__GNUC__)
710 #define TVM_ATTRIBUTE_UNUSED __attribute__((unused))
712 #define TVM_ATTRIBUTE_UNUSED
715 #define TVM_STR_CONCAT_(__x, __y) __x##__y
716 #define TVM_STR_CONCAT(__x, __y) TVM_STR_CONCAT_(__x, __y)
718 #define TVM_OBJECT_REG_VAR_DEF static TVM_ATTRIBUTE_UNUSED uint32_t __make_Object_tid
726 #define TVM_REGISTER_OBJECT_TYPE(TypeName) \
727 TVM_STR_CONCAT(TVM_OBJECT_REG_VAR_DEF, __COUNTER__) = TypeName::_GetOrAllocRuntimeTypeIndex()
733 #define TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName) \
734 TypeName(const TypeName& other) = default; \
735 TypeName(TypeName&& other) = default; \
736 TypeName& operator=(const TypeName& other) = default; \
737 TypeName& operator=(TypeName&& other) = default;
745 #define TVM_DEFINE_OBJECT_REF_METHODS_WITHOUT_DEFAULT_CONSTRUCTOR(TypeName, ParentType, \
747 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
748 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
749 const ObjectName* operator->() const { return static_cast<const ObjectName*>(data_.get()); } \
750 const ObjectName* get() const { return operator->(); } \
751 using ContainerType = ObjectName;
759 #define TVM_DEFINE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
760 TypeName() = default; \
761 TVM_DEFINE_OBJECT_REF_METHODS_WITHOUT_DEFAULT_CONSTRUCTOR(TypeName, ParentType, ObjectName)
770 #define TVM_DEFINE_NOTNULLABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
771 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
772 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
773 const ObjectName* operator->() const { return static_cast<const ObjectName*>(data_.get()); } \
774 const ObjectName* get() const { return operator->(); } \
775 static constexpr bool _type_is_nullable = false; \
776 using ContainerType = ObjectName;
786 #define TVM_DEFINE_MUTABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
787 TypeName() = default; \
788 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
789 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
790 ObjectName* operator->() const { return static_cast<ObjectName*>(data_.get()); } \
791 using ContainerType = ObjectName;
800 #define TVM_DEFINE_MUTABLE_NOTNULLABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
801 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
802 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
803 ObjectName* operator->() const { return static_cast<ObjectName*>(data_.get()); } \
804 ObjectName* get() const { return operator->(); } \
805 static constexpr bool _type_is_nullable = false; \
806 using ContainerType = ObjectName;
827 #define TVM_DEFINE_OBJECT_REF_COW_METHOD(ObjectName) \
828 static_assert(ObjectName::_type_final, \
829 "TVM's CopyOnWrite may only be used for " \
830 "Object types that are declared as final, " \
831 "using the TVM_DECLARE_FINAL_OBJECT_INFO macro."); \
832 ObjectName* CopyOnWrite() { \
833 ICHECK(data_ != nullptr); \
834 if (!data_.unique()) { \
835 auto n = make_object<ObjectName>(*(operator->())); \
836 ObjectPtr<Object>(std::move(n)).swap(data_); \
838 return static_cast<ObjectName*>(data_.get()); \
843 #if TVM_OBJECT_ATOMIC_REF_COUNTER
848 if (
ref_counter_.fetch_sub(1, std::memory_order_release) == 1) {
849 std::atomic_thread_fence(std::memory_order_acquire);
850 if (this->deleter_ !=
nullptr) {
856 inline int Object::use_count()
const {
return ref_counter_.load(std::memory_order_relaxed); }
864 if (this->deleter_ !=
nullptr) {
870 inline int Object::use_count()
const {
return ref_counter_; }
874 template <
typename TargetType>
876 const Object*
self =
this;
879 if (
self !=
nullptr) {
881 if (std::is_same<TargetType, Object>::value)
return true;
882 if (TargetType::_type_final) {
885 return self->
type_index_ == TargetType::RuntimeTypeIndex();
889 uint32_t begin = TargetType::RuntimeTypeIndex();
891 if (TargetType::_type_child_slots != 0) {
892 uint32_t end = begin + TargetType::_type_child_slots;
893 if (self->type_index_ >= begin && self->type_index_ < end)
return true;
895 if (self->type_index_ == begin)
return true;
897 if (!TargetType::_type_child_slots_can_overflow)
return false;
899 if (self->type_index_ < TargetType::RuntimeTypeIndex())
return false;
901 return self->DerivedFrom(TargetType::RuntimeTypeIndex());
910 template <
typename ObjectType,
typename>
912 if (
data_ !=
nullptr &&
data_->IsInstance<ObjectType>()) {
913 return static_cast<ObjectType*
>(
data_.get());
919 template <
typename RefType,
typename ObjType>
920 inline RefType
GetRef(
const ObjType* ptr) {
921 static_assert(std::is_base_of<typename RefType::ContainerType, ObjType>::value,
922 "Can only cast to the ref of same container type");
923 if (!RefType::_type_is_nullable) {
924 ICHECK(ptr !=
nullptr);
929 template <
typename BaseType,
typename ObjType>
931 static_assert(std::is_base_of<BaseType, ObjType>::value,
932 "Can only cast to the ref of same container type");
936 template <
typename SubRef,
typename BaseRef>
939 ICHECK(ref->template IsInstance<typename SubRef::ContainerType>())
940 <<
"Downcast from " << ref->GetTypeKey() <<
" to " << SubRef::ContainerType::_type_key
943 ICHECK(SubRef::_type_is_nullable) <<
"Downcast from nullptr to not nullable reference of "
944 << SubRef::ContainerType::_type_key;
946 return SubRef(std::move(ref.data_));
Base class of object allocators that implements make. Use curiously recurring template pattern.
Definition: memory.h:60
A custom smart pointer for Object.
Definition: object.h:363
void swap(ObjectPtr< T > &other)
Swap this array with another Object.
Definition: object.h:410
T * get() const
Definition: object.h:416
friend class Object
Definition: object.h:497
bool operator!=(const ObjectPtr< T > &other) const
Definition: object.h:467
ObjectPtr()
default constructor
Definition: object.h:366
friend ObjectPtr< BaseType > GetObjectPtr(ObjType *ptr)
Definition: object.h:930
friend class ObjectPtr
Definition: object.h:501
T * operator->() const
Definition: object.h:420
ObjectPtr(std::nullptr_t)
default constructor
Definition: object.h:368
ObjectPtr< T > & operator=(ObjectPtr< T > &&other)
move assignment
Definition: object.h:443
ObjectPtr(const ObjectPtr< T > &other)
copy constructor
Definition: object.h:373
ObjectPtr(ObjectPtr< Y > &&other)
move constructor
Definition: object.h:398
int use_count() const
Definition: object.h:461
friend ObjectRefType GetRef(const ObjType *ptr)
Definition: object.h:920
bool operator==(const ObjectPtr< T > &other) const
Definition: object.h:465
ObjectPtr(ObjectPtr< T > &&other)
move constructor
Definition: object.h:389
void reset()
reset the content of ptr to be nullptr
Definition: object.h:454
~ObjectPtr()
destructor
Definition: object.h:405
T & operator*() const
Definition: object.h:424
ObjectPtr(const ObjectPtr< U > &other)
copy constructor
Definition: object.h:380
bool operator==(std::nullptr_t null) const
Definition: object.h:469
bool operator!=(std::nullptr_t null) const
Definition: object.h:471
bool unique() const
Definition: object.h:463
ObjectPtr< T > & operator=(const ObjectPtr< T > &other)
copy assignment
Definition: object.h:432
Base class of all object reference.
Definition: object.h:520
int use_count() const
Definition: object.h:561
bool defined() const
Definition: object.h:553
static void FFIClearAfterMove(ObjectRef *ref)
Clear the object ref data field without DecRef after we successfully moved the field.
Definition: object.h:624
const Object * operator->() const
Definition: object.h:557
static constexpr bool _type_is_nullable
Definition: object.h:602
bool operator<(const ObjectRef &other) const
Comparator.
Definition: object.h:549
friend class ObjectInternal
Definition: object.h:639
bool unique() const
Definition: object.h:559
friend SubRef Downcast(BaseRef ref)
Downcast a base reference type to a more specific type.
Definition: object.h:937
ObjectRef(ObjectPtr< Object > data)
Constructor from existing object ptr.
Definition: object.h:525
ObjectRef()=default
default constructor
bool operator!=(const ObjectRef &other) const
Comparator.
Definition: object.h:543
const Object * get() const
Definition: object.h:555
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:606
static T DowncastNoCheck(ObjectRef ref)
Internal helper function downcast a ref without check.
Definition: object.h:616
const ObjectType * as() const
Try to downcast the internal Object to a raw pointer of a corresponding type.
Definition: object.h:911
bool same_as(const ObjectRef &other) const
Comparator.
Definition: object.h:531
Object * get_mutable() const
Definition: object.h:608
static ObjectPtr< ObjectType > GetDataPtr(const ObjectRef &ref)
Internal helper function get data_ as ObjectPtr of ObjectType.
Definition: object.h:632
bool operator==(const ObjectRef &other) const
Comparator.
Definition: object.h:537
base class of all object containers.
Definition: object.h:172
RefCounterType ref_counter_
The internal reference counter.
Definition: object.h:268
Object()
Definition: object.h:246
uint32_t type_index() const
Definition: object.h:180
uint32_t type_index_
Type index(tag) that indicates the type of the object.
Definition: object.h:266
std::string GetTypeKey() const
Definition: object.h:185
std::atomic< int32_t > RefCounterType
Definition: object.h:222
size_t GetTypeKeyHash() const
Definition: object.h:189
static uint32_t _GetOrAllocRuntimeTypeIndex()
Definition: object.h:229
static uint32_t TypeKey2Index(const std::string &key)
Get the type index of the corresponding key from runtime.
Object & operator=(const Object &other)
Definition: object.h:256
static size_t TypeIndex2KeyHash(uint32_t tindex)
Get the type key hash of the corresponding index from runtime.
void DecRef()
developer function, decrease reference counter.
Definition: object.h:847
static uint32_t GetOrAllocRuntimeTypeIndex(const std::string &key, uint32_t static_tindex, uint32_t parent_tindex, uint32_t type_child_slots, bool type_child_slots_can_overflow)
Get the type index using type key.
static std::string TypeIndex2Key(uint32_t tindex)
Get the type key of the corresponding index from runtime.
bool IsInstance() const
Definition: object.h:875
Object(Object &&other)
Definition: object.h:254
Object(const Object &other)
Definition: object.h:252
void IncRef()
developer function, increases reference counter.
Definition: object.h:845
static uint32_t RuntimeTypeIndex()
Definition: object.h:230
Object & operator=(Object &&other)
Definition: object.h:259
FDeleter deleter_
deleter of this object to enable customized allocation. If the deleter is nullptr,...
Definition: object.h:274
bool unique() const
Definition: object.h:908
Optional container that to represent to a Nullable variant of T.
Definition: optional.h:51
A single argument value to PackedFunc. Containing both type_code and TVMValue.
Definition: packed_func.h:796
Definition: packed_func.h:1816
Internal auxiliary struct for TypedPackedFunc to indicate a movable argument.
Definition: packed_func.h:856
Internal base class to handle conversion to POD values.
Definition: packed_func.h:615
Return Value container, Unlike TVMArgValue, which only holds reference and do not delete the underlyi...
Definition: packed_func.h:946
ObjectRefType GetRef(const ObjectType *ptr)
Get a reference type from a raw object ptr type.
ObjectPtr< BaseType > GetObjectPtr(ObjectType *ptr)
Get an object ptr type from a raw object ptr.
SubRef Downcast(BaseRef ref)
Downcast a base reference type to a more specific type.
Definition: object.h:937
Performance counters for profiling via the PAPI library.
Definition: analyzer.h:36
ObjectRef equal functor.
Definition: object.h:666
size_t operator()(const ObjectPtr< T > &a, const ObjectPtr< T > &b) const
Definition: object.h:670
bool operator()(const ObjectRef &a, const ObjectRef &b) const
Definition: object.h:667
ObjectRef hash functor.
Definition: object.h:656
size_t operator()(const ObjectPtr< T > &a) const
Definition: object.h:660
size_t operator()(const ObjectRef &a) const
Definition: object.h:657
Namespace for the list of type index.
Definition: object.h:55
@ kRoot
Root object type.
Definition: object.h:58
@ kRuntimePackedFunc
runtime::PackedFunc.
Definition: object.h:74
@ kRuntimeRPCObjectRef
runtime::RPCObjectRef
Definition: object.h:78
@ kStaticIndexEnd
Definition: object.h:80
@ kRuntimeNDArray
runtime::NDArray.
Definition: object.h:64
@ kRuntimeMap
runtime::Map.
Definition: object.h:70
@ kRuntimeString
runtime::String.
Definition: object.h:66
@ kDynamic
Type index is allocated during runtime, keeping it as constant for now to ensure compatibility across...
Definition: object.h:85
@ kRuntimeArray
runtime::Array.
Definition: object.h:68
@ kRuntimeModule
runtime::Module.
Definition: object.h:62
@ kRuntimeDiscoDRef
runtime::DRef for disco distributed runtime
Definition: object.h:76
@ kRuntimeShapeTuple
runtime::ShapeTuple.
Definition: object.h:72