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
182 std::string
GetTypeKey()
const {
return TypeIndex2Key(type_index_); }
192 template <
typename TargetType>
193 inline bool IsInstance()
const;
198 inline bool unique()
const;
218 #if TVM_OBJECT_ATOMIC_REF_COUNTER
224 static constexpr
const char* _type_key =
"runtime.Object";
230 static constexpr
bool _type_final =
false;
231 static constexpr uint32_t _type_child_slots = 0;
232 static constexpr
bool _type_child_slots_can_overflow =
true;
234 static constexpr
bool _type_has_method_visit_attrs =
true;
235 static constexpr
bool _type_has_method_sequal_reduce =
false;
236 static constexpr
bool _type_has_method_shash_reduce =
false;
263 uint32_t type_index_{0};
271 FDeleter deleter_ =
nullptr;
275 "RefCounter ABI check.");
295 uint32_t parent_tindex, uint32_t type_child_slots,
296 bool type_child_slots_can_overflow);
300 inline void IncRef();
305 inline void DecRef();
312 inline int use_count()
const;
318 bool DerivedFrom(uint32_t parent_tindex)
const;
325 friend class ObjectInternal;
340 template <
typename RelayRefType,
typename ObjectType>
351 template <
typename SubRef,
typename BaseRef>
352 inline SubRef
Downcast(BaseRef ref);
359 template <
typename T>
376 template <
typename U>
379 static_assert(std::is_base_of<T, U>::value,
380 "can only assign of child class ObjectPtr to parent");
387 : data_(other.data_) {
388 other.data_ =
nullptr;
394 template <
typename Y>
396 : data_(other.data_) {
397 static_assert(std::is_base_of<T, Y>::value,
398 "can only assign of child class ObjectPtr to parent");
399 other.data_ =
nullptr;
408 std::swap(data_, other.data_);
413 T*
get()
const {
return static_cast<T*
>(data_); }
449 explicit operator bool()
const {
return get() !=
nullptr; }
452 if (data_ !=
nullptr) {
458 int use_count()
const {
return data_ !=
nullptr ? data_->use_count() : 0; }
460 bool unique()
const {
return data_ !=
nullptr && data_->use_count() == 1; }
466 bool operator==(std::nullptr_t
null)
const {
return data_ ==
nullptr; }
468 bool operator!=(std::nullptr_t
null)
const {
return data_ !=
nullptr; }
478 if (data !=
nullptr) {
487 static ObjectPtr<T> MoveFromRValueRefArg(
Object** ref) {
506 template <
typename RelayRefType,
typename ObjType>
508 template <
typename BaseType,
typename ObjType>
513 template <
typename T>
572 template <
typename ObjectType,
typename = std::enable_if_t<std::is_base_of_v<Object, ObjectType>>>
573 inline const ObjectType*
as()
const;
592 template <
typename ObjectRefType,
593 typename = std::enable_if_t<std::is_base_of_v<ObjectRef, ObjectRefType>>>
612 template <
typename T>
614 return T(std::move(ref.
data_));
628 template <
typename ObjectType>
637 template <
typename SubRef,
typename BaseRef>
638 friend SubRef
Downcast(BaseRef ref);
649 template <
typename BaseType,
typename ObjectType>
656 template <
typename T>
658 return std::hash<Object*>()(a.
get());
666 template <
typename T>
677 #define TVM_DECLARE_BASE_OBJECT_INFO(TypeName, ParentType) \
678 static_assert(!ParentType::_type_final, "ParentObj marked as final"); \
679 static uint32_t RuntimeTypeIndex() { \
680 static_assert(TypeName::_type_child_slots == 0 || ParentType::_type_child_slots == 0 || \
681 TypeName::_type_child_slots < ParentType::_type_child_slots, \
682 "Need to set _type_child_slots when parent specifies it."); \
683 if (TypeName::_type_index != ::tvm::runtime::TypeIndex::kDynamic) { \
684 return TypeName::_type_index; \
686 return _GetOrAllocRuntimeTypeIndex(); \
688 static uint32_t _GetOrAllocRuntimeTypeIndex() { \
689 static uint32_t tindex = Object::GetOrAllocRuntimeTypeIndex( \
690 TypeName::_type_key, TypeName::_type_index, ParentType::_GetOrAllocRuntimeTypeIndex(), \
691 TypeName::_type_child_slots, TypeName::_type_child_slots_can_overflow); \
700 #define TVM_DECLARE_FINAL_OBJECT_INFO(TypeName, ParentType) \
701 static const constexpr bool _type_final = true; \
702 static const constexpr int _type_child_slots = 0; \
703 TVM_DECLARE_BASE_OBJECT_INFO(TypeName, ParentType)
706 #if defined(__GNUC__)
707 #define TVM_ATTRIBUTE_UNUSED __attribute__((unused))
709 #define TVM_ATTRIBUTE_UNUSED
712 #define TVM_STR_CONCAT_(__x, __y) __x##__y
713 #define TVM_STR_CONCAT(__x, __y) TVM_STR_CONCAT_(__x, __y)
715 #define TVM_OBJECT_REG_VAR_DEF static TVM_ATTRIBUTE_UNUSED uint32_t __make_Object_tid
723 #define TVM_REGISTER_OBJECT_TYPE(TypeName) \
724 TVM_STR_CONCAT(TVM_OBJECT_REG_VAR_DEF, __COUNTER__) = TypeName::_GetOrAllocRuntimeTypeIndex()
730 #define TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName) \
731 TypeName(const TypeName& other) = default; \
732 TypeName(TypeName&& other) = default; \
733 TypeName& operator=(const TypeName& other) = default; \
734 TypeName& operator=(TypeName&& other) = default;
742 #define TVM_DEFINE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
743 TypeName() = default; \
744 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
745 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
746 const ObjectName* operator->() const { return static_cast<const ObjectName*>(data_.get()); } \
747 const ObjectName* get() const { return operator->(); } \
748 using ContainerType = ObjectName;
757 #define TVM_DEFINE_NOTNULLABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
758 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
759 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
760 const ObjectName* operator->() const { return static_cast<const ObjectName*>(data_.get()); } \
761 const ObjectName* get() const { return operator->(); } \
762 static constexpr bool _type_is_nullable = false; \
763 using ContainerType = ObjectName;
773 #define TVM_DEFINE_MUTABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
774 TypeName() = default; \
775 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
776 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
777 ObjectName* operator->() const { return static_cast<ObjectName*>(data_.get()); } \
778 using ContainerType = ObjectName;
787 #define TVM_DEFINE_MUTABLE_NOTNULLABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
788 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
789 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
790 ObjectName* operator->() const { return static_cast<ObjectName*>(data_.get()); } \
791 ObjectName* get() const { return operator->(); } \
792 static constexpr bool _type_is_nullable = false; \
793 using ContainerType = ObjectName;
814 #define TVM_DEFINE_OBJECT_REF_COW_METHOD(ObjectName) \
815 ObjectName* CopyOnWrite() { \
816 ICHECK(data_ != nullptr); \
817 if (!data_.unique()) { \
818 auto n = make_object<ObjectName>(*(operator->())); \
819 ObjectPtr<Object>(std::move(n)).swap(data_); \
821 return static_cast<ObjectName*>(data_.get()); \
826 #if TVM_OBJECT_ATOMIC_REF_COUNTER
831 if (
ref_counter_.fetch_sub(1, std::memory_order_release) == 1) {
832 std::atomic_thread_fence(std::memory_order_acquire);
833 if (this->deleter_ !=
nullptr) {
839 inline int Object::use_count()
const {
return ref_counter_.load(std::memory_order_relaxed); }
847 if (this->deleter_ !=
nullptr) {
853 inline int Object::use_count()
const {
return ref_counter_; }
857 template <
typename TargetType>
859 const Object*
self =
this;
862 if (
self !=
nullptr) {
864 if (std::is_same<TargetType, Object>::value)
return true;
865 if (TargetType::_type_final) {
868 return self->
type_index_ == TargetType::RuntimeTypeIndex();
872 uint32_t begin = TargetType::RuntimeTypeIndex();
874 if (TargetType::_type_child_slots != 0) {
875 uint32_t end = begin + TargetType::_type_child_slots;
876 if (self->type_index_ >= begin && self->type_index_ < end)
return true;
878 if (self->type_index_ == begin)
return true;
880 if (!TargetType::_type_child_slots_can_overflow)
return false;
882 if (self->type_index_ < TargetType::RuntimeTypeIndex())
return false;
884 return self->DerivedFrom(TargetType::RuntimeTypeIndex());
893 template <
typename ObjectType,
typename>
895 if (
data_ !=
nullptr &&
data_->IsInstance<ObjectType>()) {
896 return static_cast<ObjectType*
>(
data_.get());
902 template <
typename RefType,
typename ObjType>
903 inline RefType
GetRef(
const ObjType* ptr) {
904 static_assert(std::is_base_of<typename RefType::ContainerType, ObjType>::value,
905 "Can only cast to the ref of same container type");
906 if (!RefType::_type_is_nullable) {
907 ICHECK(ptr !=
nullptr);
912 template <
typename BaseType,
typename ObjType>
914 static_assert(std::is_base_of<BaseType, ObjType>::value,
915 "Can only cast to the ref of same container type");
919 template <
typename SubRef,
typename BaseRef>
922 ICHECK(ref->template IsInstance<typename SubRef::ContainerType>())
923 <<
"Downcast from " << ref->GetTypeKey() <<
" to " << SubRef::ContainerType::_type_key
926 ICHECK(SubRef::_type_is_nullable) <<
"Downcast from nullptr to not nullable reference of "
927 << SubRef::ContainerType::_type_key;
929 return SubRef(std::move(ref.data_));
Managed reference to RelayRefTypeNode.
Definition: type.h:576
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:360
void swap(ObjectPtr< T > &other)
Swap this array with another Object.
Definition: object.h:407
T * get() const
Definition: object.h:413
friend class Object
Definition: object.h:494
bool operator!=(const ObjectPtr< T > &other) const
Definition: object.h:464
ObjectPtr()
default constructor
Definition: object.h:363
friend ObjectPtr< BaseType > GetObjectPtr(ObjType *ptr)
Definition: object.h:913
friend class ObjectPtr
Definition: object.h:498
T * operator->() const
Definition: object.h:417
friend RelayRefType GetRef(const ObjType *ptr)
Definition: object.h:903
ObjectPtr(std::nullptr_t)
default constructor
Definition: object.h:365
ObjectPtr< T > & operator=(ObjectPtr< T > &&other)
move assignment
Definition: object.h:440
ObjectPtr(const ObjectPtr< T > &other)
copy constructor
Definition: object.h:370
ObjectPtr(ObjectPtr< Y > &&other)
move constructor
Definition: object.h:395
int use_count() const
Definition: object.h:458
bool operator==(const ObjectPtr< T > &other) const
Definition: object.h:462
ObjectPtr(ObjectPtr< T > &&other)
move constructor
Definition: object.h:386
void reset()
reset the content of ptr to be nullptr
Definition: object.h:451
~ObjectPtr()
destructor
Definition: object.h:402
T & operator*() const
Definition: object.h:421
ObjectPtr(const ObjectPtr< U > &other)
copy constructor
Definition: object.h:377
bool operator==(std::nullptr_t null) const
Definition: object.h:466
bool operator!=(std::nullptr_t null) const
Definition: object.h:468
bool unique() const
Definition: object.h:460
ObjectPtr< T > & operator=(const ObjectPtr< T > &other)
copy assignment
Definition: object.h:429
Base class of all object reference.
Definition: object.h:517
int use_count() const
Definition: object.h:558
bool defined() const
Definition: object.h:550
static void FFIClearAfterMove(ObjectRef *ref)
Clear the object ref data field without DecRef after we successfully moved the field.
Definition: object.h:621
const Object * operator->() const
Definition: object.h:554
static constexpr bool _type_is_nullable
Definition: object.h:599
bool operator<(const ObjectRef &other) const
Comparator.
Definition: object.h:546
friend class ObjectInternal
Definition: object.h:636
bool unique() const
Definition: object.h:556
friend SubRef Downcast(BaseRef ref)
Downcast a base reference type to a more specific type.
Definition: object.h:920
ObjectRef(ObjectPtr< Object > data)
Constructor from existing object ptr.
Definition: object.h:522
ObjectRef()=default
default constructor
bool operator!=(const ObjectRef &other) const
Comparator.
Definition: object.h:540
const Object * get() const
Definition: object.h:552
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:603
static T DowncastNoCheck(ObjectRef ref)
Internal helper function downcast a ref without check.
Definition: object.h:613
const ObjectType * as() const
Try to downcast the internal Object to a raw pointer of a corresponding type.
Definition: object.h:894
bool same_as(const ObjectRef &other) const
Comparator.
Definition: object.h:528
Object * get_mutable() const
Definition: object.h:605
static ObjectPtr< ObjectType > GetDataPtr(const ObjectRef &ref)
Internal helper function get data_ as ObjectPtr of ObjectType.
Definition: object.h:629
bool operator==(const ObjectRef &other) const
Comparator.
Definition: object.h:534
base class of all object containers.
Definition: object.h:169
RefCounterType ref_counter_
The internal reference counter.
Definition: object.h:265
Object()
Definition: object.h:243
uint32_t type_index() const
Definition: object.h:177
uint32_t type_index_
Type index(tag) that indicates the type of the object.
Definition: object.h:263
std::string GetTypeKey() const
Definition: object.h:182
std::atomic< int32_t > RefCounterType
Definition: object.h:219
size_t GetTypeKeyHash() const
Definition: object.h:186
static uint32_t _GetOrAllocRuntimeTypeIndex()
Definition: object.h:226
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:253
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:830
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:858
Object(Object &&other)
Definition: object.h:251
Object(const Object &other)
Definition: object.h:249
void IncRef()
developer function, increases reference counter.
Definition: object.h:828
static uint32_t RuntimeTypeIndex()
Definition: object.h:227
Object & operator=(Object &&other)
Definition: object.h:256
FDeleter deleter_
deleter of this object to enable customized allocation. If the deleter is nullptr,...
Definition: object.h:271
bool unique() const
Definition: object.h:891
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:649
Definition: packed_func.h:1666
Internal auxiliary struct for TypedPackedFunc to indicate a movable argument.
Definition: packed_func.h:709
Internal base class to handle conversion to POD values.
Definition: packed_func.h:544
Return Value container, Unlike TVMArgValue, which only holds reference and do not delete the underlyi...
Definition: packed_func.h:799
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:920
RelayRefType GetRef(const ObjectType *ptr)
Get a reference type from a raw object ptr type.
runtime implementation for LibTorch/TorchScript.
Definition: analyzer.h:36
ObjectRef equal functor.
Definition: object.h:663
size_t operator()(const ObjectPtr< T > &a, const ObjectPtr< T > &b) const
Definition: object.h:667
bool operator()(const ObjectRef &a, const ObjectRef &b) const
Definition: object.h:664
ObjectRef hash functor.
Definition: object.h:653
size_t operator()(const ObjectPtr< T > &a) const
Definition: object.h:657
size_t operator()(const ObjectRef &a) const
Definition: object.h:654
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
@ kStaticIndexEnd
Definition: object.h:80
@ kRuntimeNDArray
runtime::NDArray.
Definition: object.h:64
@ kRuntimeMap
runtime::Map.
Definition: object.h:70
@ kRuntimeClosure
Definition: object.h:78
@ kRuntimeADT
Definition: object.h:79
@ kRuntimeString
runtime::String.
Definition: object.h:66
@ kDynamic
Type index is allocated during runtime.
Definition: object.h:82
@ kRuntimeArray
runtime::Array.
Definition: object.h:68
@ kRuntimeModule
runtime::Module.
Definition: object.h:62
@ kRuntimeDiscoDRef
runtime::DRef
Definition: object.h:76
@ kRuntimeShapeTuple
runtime::ShapeTuple.
Definition: object.h:72