IREE编译流程解析(六)
HAL::HALTransformPassPipeline的主要作用是进行tiling、vectorization和bufferization等操作,分配计算负载,最终生成target device的代码。比如cuda target的dispatch source code会被递降为NVVM IR。
HAL::HALTransformPassPipeline的主要作用是进行tiling、vectorization和bufferization等操作,分配计算负载,最终生成target device的代码。比如cuda target的dispatch source code会被递降为NVVM IR。
IREE::Stream::StreamTransformPassPipeline 的主要作用是将program转换到stream dialect,优化变量编码方式,划分调度子图,生成异步调度策略,并实现内存规划策略。
IREE
Flow::buildFlowTransformPassPipeline主要作用是执行一系列窥孔优化,比如1x1的conv2d转换成matmul、tiling、op
fusion等,最终将workload拆分成flow.executable
。相关的passes及其作用如下。
IREE
ABI::TransformPassPipeline主要作用是将外部导入的接口和本module导出到外部的接口参数统一成标准标量类型或hal.buffer_view
类型(hal.buffer_view
对应tensor),包含以下几个passes。
IREE CommonInputConversionPassPipeline主要作用是将IREE::Input dialect lower成IREE::Util、IREE::Flow和IREE::HAL dialect,包括以下几个passes。
IREE InputConversionPassPipeline的主要作用是将不同的输入(MHLO、XLA、Torch Tensor和TOSA)统一lower成linalg dialect和builtin的arith dialect、scf dialect和tensor dialect。下面以MHLO输入为例,列举了InputConversionPassPipeline中各个pass以及它们的主要作用。
IREE目前支持将MHLO或XLA、Torch Tensor和TOSA作为输入,经过一系列passes编译生成IREE定义的VM bytecode中间产物,其中硬件相关代码会编译成相应的Executable,保存在VM bytecode中供host进行调用,比如CUDA相关的计算代码会被lower成PTX代码,在IREE的runtime中再被CUDA的运行时以JIT的方式编译成可执行的cubin kernel。
XRT为不同的后端引擎提供了统一的上层功能和接口抽象,这些功能和接口包括:
得益于上层统一的抽象和模块化的设计,后端引擎只需要处理一些差异化的接口,并且这些差异化通常只体现在子图的编译和executable launch接口的具体实现上。
为了便于Python和C++混合编程,TVM使用了统一的PackedFunc机制。PackedFunc可以将C++中的各类函数打包成统一的函数接口,并自动导出到Python模块中进行调用,并且也支持从Python中注册一个函数,并伪装成PackedFunc在C++和Python中调用。
图替换(或者叫图改写)是一种重要的图优化技术,几乎在所有的开源框架(尤其是移动端框架)中都有应用。比如tensorflow r1.14版本中就包含了155个替换子,而且实现这些替换子的总代码量接近53k行。
一些常见的图优化技术:
DCE
CSE(公共子表达式消除)
常量折叠
数学公式简化
Op融合
Layout变换
内存优化(swap-in/swap-out、重计算)