1 高层中间代码
为了克服传统编译器中采用的IR限制DL模型中复杂计算的表达的局限性,现有的DL编译器利用高层IR(称为图IR)进行高效的代码优化设计。
1.1 图表示
基于DAG的IR:基于DAG的IR是编译器构建计算图的最传统方法之一,它将节点和边组织为有向无环图(DAG)。在DL编译器中,DAG的节点表示原子DL运算符(卷积、池等),边表示张量。该图是无环图,这与泛型编译器的数据依赖图(DDG)不同。借助于DAG计算图,DL编译器可以分析各种操作符之间的关系和依赖关系,并用它们来指导优化。在DDG上已经有很多优化,比如公共子表达式消除(CSE)和死代码消除(DCE)。通过将DL的领域知识与这些算法相结合,可以对DAG计算图进行进一步的优化。
1.2 图IR的实现
数据表示:DL编译器中的数据(例如,输入、权重和中间数据)通常以张量的形式组织,张量也称为多维数组。DL编译器可以通过内存指针直接表示张量数据,也可以通过占位符以更灵活的方式表示张量数据。占位符包含张量的每个维度的大小。
占位符(Placeholder):占位符广泛应用于符号编程。占位符只是一个具有明确形状信息(例如,每个维度中的大小)的变量,它将在计算的后期用值填充。它允许程序员在不考虑精确数据元素的情况下描述操作和构建计算图,这有助于在DL编译器中将计算定义和精确执行分离开来。
动态维度表示:在声明占位符时,通常支持未知维度大小。例如,TVM使用Any表示未知维度(例如,Tensor〈(Any,3), fp32〉);XLA使用None实现相同的目的(例如,T f.placeholder(“float”, [None,3])。未知形状表示是支持动态模型的必要条件,但是要完全支持动态模型,边界推理和维度检查应该放松。
数据布局:数据布局描述了张量在内存中的组织方式,通常是从逻辑索引到内存索引的映射。数据布局通常包括尺寸顺序(如NCHW和NHWC)、tiling、padding、striding等。TVM和Glow将数据布局表示为运算符参数,并需要此类信息进行计算和优化。Relay和MLIR将把数据布局信息添加到他们的张量类型系统中。</