
TVM IR 核心架构Expr 与 Type 的统一表达TVM 的编译栈涵盖高层 Relay/Relax 到低层 TIR均构建在tvm.ir基础设施之上其核心抽象为Expr表达式与Type类型。所有中间表示最终都归结为这两类基础节点的组合与继承 。1. 核心基类继承体系无论是用于图优化的 Relay/Relax还是用于代码生成的 TIR其算子Op定义均统一继承自RelayExprNode。这种设计确保了不同层级 IR 在元数据管理和类型推断上的一致性 。组件层级对应 C 基类主要特征源码位置参考通用表达BaseExprNode所有表达式的最顶层基类include/tvm/ir/expr.h底层原语PrimExprNode处理 POD 数据类型无生命周期管理用于 TIR 及整数分析include/tvm/ir/expr.h高层算子RelayExprNode支持张量、函数等一等公民包含类型推断结果 (checked_type_)include/tvm/ir/expr.h算子定义OpNode继承自RelayExprNode定义算子元数据名称、签名、属性include/tvm/ir/op.h2. OpNode 结构与 Support Level 解析OpNode是 TVM 中定义算子元数据的核心结构。除了常规的算子名称、类型签名和参数描述外support_level字段用于标识算子的优先级或成熟度 。C 结构定义示例/*!\ * \brief Primitive Op(builtin intrinsics)\ *\ * This data structure stores the meta-data\ * about primitive operators that can be invoked via Call.\ */\ class OpNode : public RelayExprNode {\ public:\ /*! \brief name of the operator */\ String name;\ /*! \brief the type of the operator */\ mutable FuncType op_type;\ /*! \brief detailed description of the operator */\ String description;\ /*! \brief Information of input arguments to the operator */\ ArrayAttrFieldInfo arguments;\ /*! \brief The type key of the attribute field */\ String attrs_type_key;\ /*! \brief number of input arguments to the operator, -1 means variable length */\ int32_t num_inputs -1;\ /*! \brief support level of the operator, The lower the more priority it contains. */\ int32_t support_level 10;\ // ... 其他字段如 attrs_type_index等\ };注以上代码逻辑基于 TVM 源码include/tvm/ir/op.h整理 。support_level的具体作用该字段的设计灵感来源于BLAS (Basic Linear Algebra Subprograms)的分级标准。数值含义值越小表示算子的优先级越高通常意味着该算子越基础、越稳定或被硬件支持得越好 。应用场景算子选择策略在编译器进行算子融合或 lowering 时若存在多种实现方式例如一个通用的 Python 实现和一个高度优化的 C/CUDA 实现编译器倾向于优先选择support_level更低的实现。2.稳定性标识Level 1 通常代表最核心、最稳定的内置算子而较高的 Level 可能代表实验性算子或特定后端的扩展算子。3.文档生成该字段也可用于自动生成算子文档提示用户该算子的成熟度。3. Type 系统的演进从静态到动态TVM 的类型系统直接决定了其对动态形状Dynamic Shape的支持能力这也是 Relay向 Relax 演进的关键驱动力。特性维度Relay / TIR (传统)Relax (新一代)差异解析张量类型定义TensorTypeNodeDynTensorTypeNodeRelay 将具体 Shape 表达式嵌入类型中 。Shape 存储ArrayPrimExpr shapeint ndimRelax 将 Shape 的具体值从 Type 中解耦Type 仅保留秩 (ndim) 和 dtype 。动态形状支持困难原生支持在 Relay 中Tensor[(m, n)]与Tensor[(m, 4)]被视为不同类型而在 Relax 中只要秩相同它们属于同一类型DynTensorShape 作为独立的数据流处理 。类型推断编译期严格推断运行时/混合推断解耦后避免了因 Shape 符号表达式复杂导致的类型推断失败。代码对比示例概念性# Relay/TIR 风格Shape 是类型的一部分 # TensorType(shape[m, n], dtypefloat32) # 若 m, n 变化类型即变化导致多态处理困难 # Relax 风格Shape 与类型分离 # DynTensorType(ndim2, dtypefloat32) # 具体的 shape [m, n] 作为独立的 Expr 在数据流中传递4. 编译单元IRModule所有上述的 Expr 和 Type 最终被封装在IRModule中这是 TVM 编译的最小完整单元。IRModule本质上是一个映射容器存储了全局函数BaseFunc如PrimFunc或Relay Function和类型定义 。TIR视角IRModule包含多个PrimFunc每个函数对应一个可编译的低级内核。Relay/Relax 视角IRModule包含高层函数描述了计算图的结构。统一性无论前端如何变化最终都通过IRModule传递给 Pass 机制进行优化和 Codegen 。参考来源TVM 学习指南个人版深度学习编译器Relax入门从TVM到动态图编译实战TVM 模块部署实战指南基于 C 与 Python 的完整部署示例apps/howto_deploy 解析Apache TVM 源码编译安装实战版本选择、依赖配置与踩坑完全指南TVM 代码规范与贡献指南编码风格、测试编写与常见实践要点Apache TVM 贡献者指南从提交 PR、代码评审到版本发布的完整协作流程