Object/Node
Object是所有对象容器的基类。
Node是runtime::Object的别名。
Objecgt子类的对象应该声明以下静态constexpr字段。
_type_index
对象的静态类型索引,并非当前对象的类型索引,旨在被子类作为默认值使用。如果设置为TypeIndex::kDynamic,类型索引将在运行时分配。<br /> 运行时类型索引可以通过ObjectType::TypeIndex()访问。
_type_key
type类型的唯一字符串标识符。
_type_final
类型是否为终端类型(在对象系统中没有该类型的子类),该字段由marco TVM_DECLARE_FINAL_OBJECT_INFO自动设置。<br /> 对于终端对象类型T的子类,使用make_object构造它仍然是可以的,但IsInstance检查只会显示对象类型为T(而不是子类)。
以下两个字段是可以被子类化的基类所必需的:
_type_child_slots:
为子类保留的类型索引槽的数量。用于IsInstance中类型检查的运行时优化。<br /> 如果一个对象的type_index在[type_index, type_index + _type_child_slots]的范围内,则可以快速判定该对象为当前对象类的子类,如果不是,则使用回退机制检查全局类型表。<br /> 建议:设置为估计需要的子类数量。
_type_child_slots_can_overflow:
即使子类的数量超过了_type_child_slots,我们是否可以添加额外的子类。将使用一个后备机制来检查全局类型表。<br /> 建议:如果我们知道确切的子代数量,为了优化运行速度,将其设置为false。
用于在对象中声明辅助函数的两个宏:
- TVM_DECLARE_BASE_OBJECT_INFO 用于可以被子类化的对象类.
- TVM_DECLARE_FINAL_OBJECT_INFO 用于不可以被子类化的对象类。
新的对象可以使用make_object函数来创建,这将自动设置对象的type_index和deleter。
部分源码如下:
class Object {
public:
/*!
* Check if the object is an instance of TargetType.
* \tparam TargetType The target type to be checked.
* \return Whether the target type is true.
*/
template<typename TargetType>
inline bool IsInstance() const;
static constexpr const char* _type_key = "Object";
// Default object type properties for sub-classes
static constexpr bool _type_final = false;
static constexpr uint32_t _type_child_slots = 0;
static constexpr bool _type_child_slots_can_overflow = true;
// NOTE: the following field is not type index of Object
// but was intended to be used by sub-classes as default value.
// The type index of Object is TypeIndex::kRoot
static constexpr uint32_t _type_index = TypeIndex::kDynamic;
protected:
// The fields of the base object cell.
/*! \brief Type index(tag) that indicates the type of the object. */
uint32_t type_index_{0};
/*! \brief The internal reference counter */
RefCounterType ref_counter_{0};
/*!
* \brief deleter of this object to enable customized allocation.
* If the deleter is nullptr, no deletion will be performed.
* The creator of the object must always set the deleter field properly.
*/
FDeleter deleter_ = nullptr;
private:
/*!
* \return The usage count of the cell.
* \note We use stl style naming to be consistent with known API in shared_ptr.
*/
inline int use_count() const;
/*!
* \brief Check of this object is derived from the parent.
* \param parent_tindex The parent type index.
* \return The derivation results.
*/
TVM_DLL bool DerivedFrom(uint32_t parent_tindex) const;
};
ObjectPtr
ObjectPtr是Object的自定义智能指针。
它是一个模板类。部分源码如下:
template <typename T>
class ObjectPtr {
...
public:
/*!
* \return Get the content of the pointer
*/
T* get() const {
return static_cast<T*>(data_);
}
/*!
* \return The pointer
*/
T* operator->() const {
return get();
}
/*!
* \return The reference
*/
T& operator*() const { // NOLINT(*)
return *get();
}
private:
/*! \brief internal pointer field */
Object* data_{nullptr};
...
}
它唯一的字段是Object data. 一般的,T是Object的子类。它的函数get()可以将data变成T。
ObjectRef
ObjectRef是所有对象引用的基类。
部分源码如下:
/*! \brief Base class of all object reference */
class ObjectRef {
public:
/*!
* \brief Comparator
* \param other Another object ref.
* \return the compare result.
*/
bool same_as(const ObjectRef& other) const {
return data_ == other.data_;
}
/*! \return whether the expression is null */
bool defined() const {
return data_ != nullptr;//注意,在ObjectPtr中重载了!=,所以这里是没有问题的。
}
/*! \return the internal object pointer */
const Object* get() const {
return data_.get();
}
/*! \return the internal object pointer */
const Object* operator->() const {
return get();
}
/*!
* \brief Try to downcast the internal Object to a
* raw pointer of a corresponding type.
*
* The function will return a nullptr if the cast failed.
*
* if (const Add *add = node_ref.As<Add>()) {
* // This is an add node
* }
* \tparam ObjectType the target type, must be a subtype of Object/
*/
template <typename ObjectType>
inline const ObjectType* as() const;
/*! \brief type indicate the container type. */
using ContainerType = Object;
protected:
/*! \brief Internal pointer that backs the reference. */
ObjectPtr<Object> data_;
/*!
* \brief Internal helper function downcast a ref without check.
* \note Only used for internal dev purposes.
* \tparam T The target reference type.
* \return The casted result.
*/
template<typename T>
static T DowncastNoCheck(ObjectRef ref) {
return T(std::move(ref.data_));
}
/*!
* \brief Internal helper function get data_ as ObjectPtr of ObjectType.
* \note only used for internal dev purpose.
* \tparam ObjectType The corresponding object type.
* \return the corresponding type.
*/
template<typename ObjectType>
static ObjectPtr<ObjectType> GetDataPtr(const ObjectRef& ref) {
return ObjectPtr<ObjectType>(ref.data_.data_);
}
};
该类含有一个字段是ObjectPtr