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
180 std::string
GetTypeKey()
const {
return TypeIndex2Key(type_index_); }
190 template <
typename TargetType>
191 inline bool IsInstance()
const;
196 inline bool unique()
const;
216 #if TVM_OBJECT_ATOMIC_REF_COUNTER
222 static constexpr
const char* _type_key =
"runtime.Object";
228 static constexpr
bool _type_final =
false;
229 static constexpr uint32_t _type_child_slots = 0;
230 static constexpr
bool _type_child_slots_can_overflow =
true;
232 static constexpr
bool _type_has_method_visit_attrs =
true;
233 static constexpr
bool _type_has_method_sequal_reduce =
false;
234 static constexpr
bool _type_has_method_shash_reduce =
false;
261 uint32_t type_index_{0};
269 FDeleter deleter_ =
nullptr;
273 "RefCounter ABI check.");
293 uint32_t parent_tindex, uint32_t type_child_slots,
294 bool type_child_slots_can_overflow);
298 inline void IncRef();
303 inline void DecRef();
310 inline int use_count()
const;
316 bool DerivedFrom(uint32_t parent_tindex)
const;
323 friend class ObjectInternal;
338 template <
typename RelayRefType,
typename ObjectType>
349 template <
typename SubRef,
typename BaseRef>
350 inline SubRef
Downcast(BaseRef ref);
357 template <
typename T>
374 template <
typename U>
377 static_assert(std::is_base_of<T, U>::value,
378 "can only assign of child class ObjectPtr to parent");
385 : data_(other.data_) {
386 other.data_ =
nullptr;
392 template <
typename Y>
394 : data_(other.data_) {
395 static_assert(std::is_base_of<T, Y>::value,
396 "can only assign of child class ObjectPtr to parent");
397 other.data_ =
nullptr;
406 std::swap(data_, other.data_);
411 T*
get()
const {
return static_cast<T*
>(data_); }
447 explicit operator bool()
const {
return get() !=
nullptr; }
450 if (data_ !=
nullptr) {
456 int use_count()
const {
return data_ !=
nullptr ? data_->use_count() : 0; }
458 bool unique()
const {
return data_ !=
nullptr && data_->use_count() == 1; }
464 bool operator==(std::nullptr_t
null)
const {
return data_ ==
nullptr; }
466 bool operator!=(std::nullptr_t
null)
const {
return data_ !=
nullptr; }
476 if (data !=
nullptr) {
485 static ObjectPtr<T> MoveFromRValueRefArg(
Object** ref) {
504 template <
typename RelayRefType,
typename ObjType>
506 template <
typename BaseType,
typename ObjType>
511 template <
typename T>
570 template <
typename ObjectType,
typename = std::enable_if_t<std::is_base_of_v<Object, ObjectType>>>
571 inline const ObjectType*
as()
const;
590 template <
typename ObjectRefType,
591 typename = std::enable_if_t<std::is_base_of_v<ObjectRef, ObjectRefType>>>
610 template <
typename T>
612 return T(std::move(ref.
data_));
626 template <
typename ObjectType>
635 template <
typename SubRef,
typename BaseRef>
636 friend SubRef
Downcast(BaseRef ref);
647 template <
typename BaseType,
typename ObjectType>
654 template <
typename T>
656 return std::hash<Object*>()(a.
get());
664 template <
typename T>
675 #define TVM_DECLARE_BASE_OBJECT_INFO(TypeName, ParentType) \
676 static_assert(!ParentType::_type_final, "ParentObj marked as final"); \
677 static uint32_t RuntimeTypeIndex() { \
678 static_assert(TypeName::_type_child_slots == 0 || ParentType::_type_child_slots == 0 || \
679 TypeName::_type_child_slots < ParentType::_type_child_slots, \
680 "Need to set _type_child_slots when parent specifies it."); \
681 if (TypeName::_type_index != ::tvm::runtime::TypeIndex::kDynamic) { \
682 return TypeName::_type_index; \
684 return _GetOrAllocRuntimeTypeIndex(); \
686 static uint32_t _GetOrAllocRuntimeTypeIndex() { \
687 static uint32_t tindex = Object::GetOrAllocRuntimeTypeIndex( \
688 TypeName::_type_key, TypeName::_type_index, ParentType::_GetOrAllocRuntimeTypeIndex(), \
689 TypeName::_type_child_slots, TypeName::_type_child_slots_can_overflow); \
698 #define TVM_DECLARE_FINAL_OBJECT_INFO(TypeName, ParentType) \
699 static const constexpr bool _type_final = true; \
700 static const constexpr int _type_child_slots = 0; \
701 TVM_DECLARE_BASE_OBJECT_INFO(TypeName, ParentType)
704 #if defined(__GNUC__)
705 #define TVM_ATTRIBUTE_UNUSED __attribute__((unused))
707 #define TVM_ATTRIBUTE_UNUSED
710 #define TVM_STR_CONCAT_(__x, __y) __x##__y
711 #define TVM_STR_CONCAT(__x, __y) TVM_STR_CONCAT_(__x, __y)
713 #define TVM_OBJECT_REG_VAR_DEF static TVM_ATTRIBUTE_UNUSED uint32_t __make_Object_tid
721 #define TVM_REGISTER_OBJECT_TYPE(TypeName) \
722 TVM_STR_CONCAT(TVM_OBJECT_REG_VAR_DEF, __COUNTER__) = TypeName::_GetOrAllocRuntimeTypeIndex()
728 #define TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName) \
729 TypeName(const TypeName& other) = default; \
730 TypeName(TypeName&& other) = default; \
731 TypeName& operator=(const TypeName& other) = default; \
732 TypeName& operator=(TypeName&& other) = default;
740 #define TVM_DEFINE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
741 TypeName() = default; \
742 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
743 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
744 const ObjectName* operator->() const { return static_cast<const ObjectName*>(data_.get()); } \
745 const ObjectName* get() const { return operator->(); } \
746 using ContainerType = ObjectName;
755 #define TVM_DEFINE_NOTNULLABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
756 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
757 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
758 const ObjectName* operator->() const { return static_cast<const ObjectName*>(data_.get()); } \
759 const ObjectName* get() const { return operator->(); } \
760 static constexpr bool _type_is_nullable = false; \
761 using ContainerType = ObjectName;
771 #define TVM_DEFINE_MUTABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
772 TypeName() = default; \
773 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
774 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
775 ObjectName* operator->() const { return static_cast<ObjectName*>(data_.get()); } \
776 using ContainerType = ObjectName;
785 #define TVM_DEFINE_MUTABLE_NOTNULLABLE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName) \
786 explicit TypeName(::tvm::runtime::ObjectPtr<::tvm::runtime::Object> n) : ParentType(n) {} \
787 TVM_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(TypeName); \
788 ObjectName* operator->() const { return static_cast<ObjectName*>(data_.get()); } \
789 ObjectName* get() const { return operator->(); } \
790 static constexpr bool _type_is_nullable = false; \
791 using ContainerType = ObjectName;
812 #define TVM_DEFINE_OBJECT_REF_COW_METHOD(ObjectName) \
813 ObjectName* CopyOnWrite() { \
814 ICHECK(data_ != nullptr); \
815 if (!data_.unique()) { \
816 auto n = make_object<ObjectName>(*(operator->())); \
817 ObjectPtr<Object>(std::move(n)).swap(data_); \
819 return static_cast<ObjectName*>(data_.get()); \
824 #if TVM_OBJECT_ATOMIC_REF_COUNTER
829 if (
ref_counter_.fetch_sub(1, std::memory_order_release) == 1) {
830 std::atomic_thread_fence(std::memory_order_acquire);
831 if (this->deleter_ !=
nullptr) {
837 inline int Object::use_count()
const {
return ref_counter_.load(std::memory_order_relaxed); }
845 if (this->deleter_ !=
nullptr) {
851 inline int Object::use_count()
const {
return ref_counter_; }
855 template <
typename TargetType>
857 const Object*
self =
this;
860 if (
self !=
nullptr) {
862 if (std::is_same<TargetType, Object>::value)
return true;
863 if (TargetType::_type_final) {
866 return self->
type_index_ == TargetType::RuntimeTypeIndex();
870 uint32_t begin = TargetType::RuntimeTypeIndex();
872 if (TargetType::_type_child_slots != 0) {
873 uint32_t end = begin + TargetType::_type_child_slots;
874 if (self->type_index_ >= begin && self->type_index_ < end)
return true;
876 if (self->type_index_ == begin)
return true;
878 if (!TargetType::_type_child_slots_can_overflow)
return false;
880 if (self->type_index_ < TargetType::RuntimeTypeIndex())
return false;
882 return self->DerivedFrom(TargetType::RuntimeTypeIndex());
891 template <
typename ObjectType,
typename>
893 if (
data_ !=
nullptr &&
data_->IsInstance<ObjectType>()) {
894 return static_cast<ObjectType*
>(
data_.get());
900 template <
typename RefType,
typename ObjType>
901 inline RefType
GetRef(
const ObjType* ptr) {
902 static_assert(std::is_base_of<typename RefType::ContainerType, ObjType>::value,
903 "Can only cast to the ref of same container type");
904 if (!RefType::_type_is_nullable) {
905 ICHECK(ptr !=
nullptr);
910 template <
typename BaseType,
typename ObjType>
912 static_assert(std::is_base_of<BaseType, ObjType>::value,
913 "Can only cast to the ref of same container type");
917 template <
typename SubRef,
typename BaseRef>
920 ICHECK(ref->template IsInstance<typename SubRef::ContainerType>())
921 <<
"Downcast from " << ref->GetTypeKey() <<
" to " << SubRef::ContainerType::_type_key
924 ICHECK(SubRef::_type_is_nullable) <<
"Downcast from nullptr to not nullable reference of "
925 << SubRef::ContainerType::_type_key;
927 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:358
void swap(ObjectPtr< T > &other)
Swap this array with another Object.
Definition: object.h:405
T * get() const
Definition: object.h:411
friend class Object
Definition: object.h:492
bool operator!=(const ObjectPtr< T > &other) const
Definition: object.h:462
ObjectPtr()
default constructor
Definition: object.h:361
friend ObjectPtr< BaseType > GetObjectPtr(ObjType *ptr)
Definition: object.h:911
friend class ObjectPtr
Definition: object.h:496
T * operator->() const
Definition: object.h:415
friend RelayRefType GetRef(const ObjType *ptr)
Definition: object.h:901
ObjectPtr(std::nullptr_t)
default constructor
Definition: object.h:363
ObjectPtr< T > & operator=(ObjectPtr< T > &&other)
move assignment
Definition: object.h:438
ObjectPtr(const ObjectPtr< T > &other)
copy constructor
Definition: object.h:368
ObjectPtr(ObjectPtr< Y > &&other)
move constructor
Definition: object.h:393
int use_count() const
Definition: object.h:456
bool operator==(const ObjectPtr< T > &other) const
Definition: object.h:460
ObjectPtr(ObjectPtr< T > &&other)
move constructor
Definition: object.h:384
void reset()
reset the content of ptr to be nullptr
Definition: object.h:449
~ObjectPtr()
destructor
Definition: object.h:400
T & operator*() const
Definition: object.h:419
ObjectPtr(const ObjectPtr< U > &other)
copy constructor
Definition: object.h:375
bool operator==(std::nullptr_t null) const
Definition: object.h:464
bool operator!=(std::nullptr_t null) const
Definition: object.h:466
bool unique() const
Definition: object.h:458
ObjectPtr< T > & operator=(const ObjectPtr< T > &other)
copy assignment
Definition: object.h:427
Base class of all object reference.
Definition: object.h:515
int use_count() const
Definition: object.h:556
bool defined() const
Definition: object.h:548
static void FFIClearAfterMove(ObjectRef *ref)
Clear the object ref data field without DecRef after we successfully moved the field.
Definition: object.h:619
const Object * operator->() const
Definition: object.h:552
static constexpr bool _type_is_nullable
Definition: object.h:597
bool operator<(const ObjectRef &other) const
Comparator.
Definition: object.h:544
friend class ObjectInternal
Definition: object.h:634
bool unique() const
Definition: object.h:554
friend SubRef Downcast(BaseRef ref)
Downcast a base reference type to a more specific type.
Definition: object.h:918
ObjectRef(ObjectPtr< Object > data)
Constructor from existing object ptr.
Definition: object.h:520
ObjectRef()=default
default constructor
bool operator!=(const ObjectRef &other) const
Comparator.
Definition: object.h:538
const Object * get() const
Definition: object.h:550
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:601
static T DowncastNoCheck(ObjectRef ref)
Internal helper function downcast a ref without check.
Definition: object.h:611
const ObjectType * as() const
Try to downcast the internal Object to a raw pointer of a corresponding type.
Definition: object.h:892
bool same_as(const ObjectRef &other) const
Comparator.
Definition: object.h:526
Object * get_mutable() const
Definition: object.h:603
static ObjectPtr< ObjectType > GetDataPtr(const ObjectRef &ref)
Internal helper function get data_ as ObjectPtr of ObjectType.
Definition: object.h:627
bool operator==(const ObjectRef &other) const
Comparator.
Definition: object.h:532
base class of all object containers.
Definition: object.h:167
RefCounterType ref_counter_
The internal reference counter.
Definition: object.h:263
Object()
Definition: object.h:241
uint32_t type_index() const
Definition: object.h:175
uint32_t type_index_
Type index(tag) that indicates the type of the object.
Definition: object.h:261
std::string GetTypeKey() const
Definition: object.h:180
std::atomic< int32_t > RefCounterType
Definition: object.h:217
size_t GetTypeKeyHash() const
Definition: object.h:184
static uint32_t _GetOrAllocRuntimeTypeIndex()
Definition: object.h:224
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:251
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:828
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:856
Object(Object &&other)
Definition: object.h:249
Object(const Object &other)
Definition: object.h:247
void IncRef()
developer function, increases reference counter.
Definition: object.h:826
static uint32_t RuntimeTypeIndex()
Definition: object.h:225
Object & operator=(Object &&other)
Definition: object.h:254
FDeleter deleter_
deleter of this object to enable customized allocation. If the deleter is nullptr,...
Definition: object.h:269
bool unique() const
Definition: object.h:889
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:646
Definition: packed_func.h:1517
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:541
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:918
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:661
size_t operator()(const ObjectPtr< T > &a, const ObjectPtr< T > &b) const
Definition: object.h:665
bool operator()(const ObjectRef &a, const ObjectRef &b) const
Definition: object.h:662
ObjectRef hash functor.
Definition: object.h:651
size_t operator()(const ObjectPtr< T > &a) const
Definition: object.h:655
size_t operator()(const ObjectRef &a) const
Definition: object.h:652
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:78
@ kRuntimeNDArray
runtime::NDArray.
Definition: object.h:64
@ kRuntimeMap
runtime::Map.
Definition: object.h:70
@ kRuntimeClosure
Definition: object.h:76
@ kRuntimeADT
Definition: object.h:77
@ kRuntimeString
runtime::String.
Definition: object.h:66
@ kDynamic
Type index is allocated during runtime.
Definition: object.h:80
@ kRuntimeArray
runtime::Array.
Definition: object.h:68
@ kRuntimeModule
runtime::Module.
Definition: object.h:62
@ kRuntimeShapeTuple
runtime::ShapeTuple.
Definition: object.h:72