first commit
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
# 阶段 7:运行时(VM + iree-runtime)✅
|
||||
|
||||
> 2026-08-15。对应规划阶段 7。分两部分:
|
||||
> **编译侧** `src/iree/compiler/src/iree/compiler/Dialect/VM/`(生成字节码)
|
||||
> **运行时** `src/iree/runtime/src/iree/`(C 实现)。
|
||||
|
||||
## 1. 整体图景
|
||||
|
||||
编译的最后一步是把 HAL 模块序列化成 **VM 字节码**(`.vmfb`),运行时加载并解释执行:
|
||||
|
||||
```
|
||||
HAL 模块 → VM 转换(HALToVM)→ vm.module(字节码 IR)→ 序列化 → .vmfb 文件
|
||||
↓
|
||||
iree-runtime 加载 → VM 解释器 → 调 hal.* import → HAL driver 执行
|
||||
```
|
||||
|
||||
## 2. VM = 紧凑字节码虚拟机(编译侧)
|
||||
|
||||
VM dialect 定义了一套**字节码级的 IR**,核心 op(`IR/VMOps.td`):
|
||||
|
||||
| op | 作用 |
|
||||
|---|---|
|
||||
| `vm.module` | 顶层字节码模块 |
|
||||
| `vm.func` | VM 函数 |
|
||||
| `vm.import` / `vm.export` | 导入外部函数(如 `hal.command_buffer.dispatch`)/ 导出 |
|
||||
| `vm.call` / `vm.call.variadic` / `vm.call.yieldable` | 调用(含可让出调用,协作式调度) |
|
||||
| `vm.branch` / `vm.cond_branch` / `vm.branch_table` | 字节码级控制流 |
|
||||
| `vm.global.load/store.ref` | 全局引用变量 |
|
||||
| `vm.const.ref.rodata/zero` | 常量 |
|
||||
| `vm.list.*` / `vm.buffer.*` | 列表 / buffer 操作 |
|
||||
| `vm.discard.refs` | **引用计数回收**(显式 GC) |
|
||||
|
||||
### 字节码格式
|
||||
|
||||
用 **FlatBuffers** 定义(`runtime/src/iree/schemas/bytecode_module_def.fbs`),
|
||||
是紧凑、可直接 mmap 加载的二进制格式。阶段 2 用 `iree-dump-module` 看到的就是反汇编:
|
||||
|
||||
```
|
||||
Required Types: i32, i64, !hal.allocator, !hal.buffer, !hal.buffer_view,
|
||||
!hal.command_buffer, !hal.device, !hal.executable, !hal.fence, !vm.buffer
|
||||
Module Dependencies: hal, version >= 6
|
||||
Imported Functions:
|
||||
[ 7] hal.command_buffer.dispatch(...) -> ()
|
||||
[11] hal.device.queue.execute.indirect(...) -> ()
|
||||
[16] hal.fence.await(i32, i64, tuple<!vm.ref<?>>...) -> (i32)
|
||||
```
|
||||
|
||||
## 3. iree-runtime(C 运行时)
|
||||
|
||||
`runtime/src/iree/` 目录:
|
||||
|
||||
| 目录 | 作用 |
|
||||
|---|---|
|
||||
| `vm/` + `vm/bytecode/` | **VM 解释器**(字节码解码 + 分发执行) |
|
||||
| `hal/` + `hal/drivers/` | HAL 运行时 + 各设备驱动 |
|
||||
| `task/` | 多线程任务调度系统(local-task driver 的基础) |
|
||||
| `base/` | 基础工具(status、allocator、logging) |
|
||||
| `builtins/` / `modules/` | VM 内置函数 / 内置模块(如 hal 模块) |
|
||||
| `schemas/` | FlatBuffers schema(字节码 + 各后端可执行体格式) |
|
||||
| `runtime/` | 顶层 API(`iree_runtime_instance` 等) |
|
||||
| `io/` | 参数/文件 IO |
|
||||
|
||||
### HAL drivers(真正的设备后端)
|
||||
|
||||
`hal/drivers/` 下每个目录是一个设备实现:
|
||||
|
||||
| driver | 设备 |
|
||||
|---|---|
|
||||
| `local_task` | **CPU 多线程**(基于 task 系统)—— 默认 |
|
||||
| `local_sync` | CPU 同步(调试用) |
|
||||
| `cuda` / `hip` / `amdgpu` | NVIDIA / AMD GPU |
|
||||
| `vulkan` | Vulkan |
|
||||
| `metal` | Apple Metal |
|
||||
| `webgpu` | WebGPU |
|
||||
| `null` | 空设备(测试) |
|
||||
|
||||
> 当前环境只装了 base 包,运行时只有 local-task/local-sync。CUDA driver 需要额外构建。
|
||||
|
||||
## 4. 与 TVM 0.6 对照
|
||||
|
||||
| IREE | TVM 0.6 |
|
||||
|---|---|
|
||||
| VM 字节码(.vmfb) | graph runtime / relay VM 的序列化 |
|
||||
| vm.import(hal.*) | 生成的 kernel 调用 |
|
||||
| HAL driver(local-task/cuda/vulkan) | DeviceAPI(CPU/CUDA/OpenCL/Metal) |
|
||||
| task 系统 | CPU 线程池 runtime |
|
||||
| 引用计数 GC | 无(TVM 用 DLTensor 引用计数) |
|
||||
|
||||
**核心差异**:IREE 的 VM 是**完整字节码虚拟机**(带控制流、全局变量、yieldable 调用),
|
||||
而 TVM 的 graph runtime 只是「按拓扑顺序执行节点」。IREE 的 VM 更接近一个真正的 VM。
|
||||
|
||||
## 5. 源码阅读路径
|
||||
|
||||
```
|
||||
# 编译侧(字节码生成)
|
||||
src/iree/compiler/src/iree/compiler/Dialect/VM/
|
||||
├── IR/VMOps.td # VM op 定义
|
||||
├── Conversion/HALToVM/ # HAL → VM 转换
|
||||
└── Target/ # 序列化到字节码
|
||||
|
||||
# 运行时(C)
|
||||
src/iree/runtime/src/iree/
|
||||
├── vm/ # VM 解释器
|
||||
├── hal/drivers/local_task/ # CPU 多线程 driver(默认)
|
||||
├── hal/drivers/cuda/ # CUDA driver
|
||||
├── task/ # 任务调度
|
||||
└── schemas/bytecode_module_def.fbs # 字节码格式
|
||||
```
|
||||
|
||||
## 6. 全流程回顾(7 个阶段串起来)
|
||||
|
||||
```
|
||||
输入(StableHLO/TOSA) → [前端] → linalg → [Flow] dispatch 划分 → [Stream] 异步调度
|
||||
→ [HAL] 设备抽象 + 触发 codegen → [Codegen] linalg→LLVM/SPIR-V → [VM] 字节码 → [runtime] 执行
|
||||
```
|
||||
|
||||
你现在已经把 IREE 从输入到运行时**完整走了一遍**。每个阶段都有对应笔记和源码路径。
|
||||
|
||||
## 下一步(阶段 8 实践,可选)
|
||||
|
||||
- 写一个自定义 pass(如自定义 fusion 规则),需要源码构建
|
||||
- 配 CUDA 后端,看 GPU 的 codegen(LLVMGPU → NVVM)
|
||||
- 深入某一层读源码(建议 Stream 或 Codegen)
|
||||
Reference in New Issue
Block a user