first commit

This commit is contained in:
ylhan
2026-08-20 17:20:09 +08:00
commit 8049b6f58d
14 changed files with 1649 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
# 阶段 4a:Flow(图级优化 + dispatch 划分)✅
> 2026-08-15。对应规划阶段 4 前半。源码:`src/iree/compiler/src/iree/compiler/Dialect/Flow/`。
> IR 变换示例见 [02-architecture.md](02-architecture.md) 边界 2。
## 1. Flow 的职责
Flow 是 IREE 的**图级 IR**,在输入方言(linalg)和 Stream(异步)之间。两大职责:
1. **图级优化**:算子融合(fusion)、reshape 折叠、类型推导、量化转换、全局常量处理等
2. **dispatch 划分**:把图切成一个个 **dispatch region**,再 outline 成独立的 `flow.executable`
—— 每个 dispatch = 一个可独立编译执行的 kernel(对应 TVM 里划分出的一个 kernel)
## 2. 核心 op(定义在 `IR/FlowOps.td`)
| op | 作用 |
|---|---|
| `flow.tensor.empty/load/store/slice/reshape/update` | Flow 层的张量操作(值语义) |
| `flow.tensor.barrier` | 张量屏障,标记 dispatch 边界(前身是 `iree_tensor_ext.compute_barrier`) |
| `flow.tensor.transfer` | 跨设备张量传输 |
| `flow.dispatch.region` | **dispatch region**:一个可执行单元(核心) |
| `flow.dispatch` / `flow.dispatch.workgroups` | 调用 dispatch(启动一个 kernel) |
| `flow.executable` / `flow.executable.export` | 可执行体 + 导出点 |
| `flow.dispatch.workgroup_count/id/size` | workgroup 相关内建 |
| `flow.channel.*` + `flow.collective.*` | 多设备通信(AllGather/AllReduce/AllToAll/SendRecv) |
| `flow.parameter.load/write` | 参数(权重)处理 |
## 3. 关键 pass(`Transforms/` 目录)
| pass | 文件 | 作用 |
|---|---|---|
| `ConvertToFlowPass` | ConvertToFlow.cpp | 输入方言 → Flow |
| `FusionPreprocessingPass` / `ElementwiseOpFusionPass` / `FuseMultiUseElementwiseProducerPass` | (dispatch creation) | **算子融合**(elementwise 融合进 reduce/matmul) |
| `FormDispatchRegionsPass` | FormDispatchRegions.cpp | **形成 dispatch region**(核心) |
| `CloneProducersIntoDispatchRegionsPass` | (dispatch creation) | 把 producer 克隆进 dispatch region |
| `ConvertDispatchRegionsToWorkgroupsPass` | ConvertRegionToWorkgroups.cpp | dispatch region → workgroup 语义 |
| `OutlineDispatchRegionsPass` | OutlineDispatchRegions.cpp | **outline 成 flow.executable** |
| `DeduplicateExecutablesPass` | DeduplicateExecutables.cpp | 去重相同 executable |
| `CleanupTensorShapesPass` / `CaptureDynamicDimsPass` | 同名 .cpp | 形状清理 / 动态维度捕获 |
## 4. dispatch region 形成(核心概念)
**dispatch region = 一个要交给 codegen 独立编译的计算单元**(对应一个 kernel 启动)。
形成逻辑(`FormDispatchRegionsPass`):
1. 以「root op」(如 `linalg.matmul`、reduction)为锚点
2. 把可融合的 elementwise producer 克隆进同一个 region(fusion)
3. 用 `flow.tensor.barrier` 标记 region 的输入/输出边界
4. 后续 outline 成 `flow.executable`
IR 变化(阶段 2 已见,精简):
```mlir
// FormDispatchRegionsPass 之后:matmul + fill 被包进 dispatch.region
%6 = flow.dispatch.region -> (tensor<2x2xf32>) {
%8 = linalg.fill ins(%cst : f32) outs(%7 : tensor<2x2xf32>) -> tensor<2x2xf32>
%9 = linalg.matmul ins(%1, %3 : ...) outs(%8 : ...) -> tensor<2x2xf32>
flow.return %9 : tensor<2x2xf32>
}
// OutlineDispatchRegionsPass 之后:outline 成 executable,主函数只剩 flow.dispatch 调用
flow.executable private @matmul_dispatch_0 { ... } // 独立的可执行体
%2 = flow.dispatch @matmul_dispatch_0::@matmul_dispatch_0_matmul_2x2x4_f32(%0, %1) : ...
```
## 5. 与 TVM 0.6 对照
| IREE Flow | TVM 0.6 Relay |
|---|---|
| 图级优化(fusion/reshape/type propagation) | Relay 的 fusion / 图优化 pass |
| dispatch region 形成 | 确定哪些算子合成一个 kernel(relay fusion 后的分组) |
| flow.executable | 一个编译好的 kernel |
| flow.tensor.*(值语义张量) | Relay 的 TensorType 表达式 |
| flow.collective.* | Relay 里的通信算子(较晚版本才有) |
## 6. 源码阅读路径
```
src/iree/compiler/src/iree/compiler/Dialect/Flow/
├── IR/FlowOps.td # op 定义(TableGen)—— 先读这个,认识所有 op
├── IR/FlowOps.cpp # op 实现(verifier、folder、builder)
├── IR/FlowInterfaces.td # 接口定义(如 Dispatchable/Partitionable)
├── Transforms/FormDispatchRegions.cpp # dispatch 划分核心算法
├── Transforms/OutlineDispatchRegions.cpp
├── Transforms/ConvertRegionToWorkgroups.cpp
└── Conversion/TensorToFlow/ # tensor → flow 转换
```
> 学习建议:先读 `FlowOps.td` 认 op,再看 `FormDispatchRegions.cpp` 理解划分算法。
> 划分算法在 IREE 3.x 已重构为基于「partitionable interface + workload」的方式
> (不是老的 DispatchableOpInterface),读的时候注意版本。