Files
note_AI_compiler/iree/06-stream.md
T
2026-08-20 17:20:09 +08:00

6.3 KiB
Raw Blame History

阶段 4b:Stream(异步调度)✅

2026-08-15。对应规划阶段 4 后半。源码:src/iree/compiler/src/iree/compiler/Dialect/Stream/。 这是 IREE 最有特色、也是 TVM 没有对应物的一层,值得重点理解。

1. Stream 的职责:把同步图变成异步执行模型

Flow 层产出的还是「同步的图」(每个 op 依赖前一个的 result)。Stream 层把它变成异步执行模型:

  • 每个计算(dispatch)变成可异步提交的工作
  • 用 timepoint(类似 future/fence)显式表达「某批异步工作何时完成」
  • 用 resource 管理内存的生命周期(分配/持有/释放)
  • 用 affinity 标注每个 op 在哪个设备上执行

这一层是 IREE 支持多设备异步调度的核心。

2. 核心概念

(1) timepoint —— 异步同步原语(灵魂)

!stream.timepoint = 一个「未来某个时刻会完成」的句柄,用来表达数据依赖和同步:

// stream.async.execute 提交一批异步工作,返回 (results, timepoint)
%results, %result_timepoint = stream.async.execute ... {
  %4 = stream.async.dispatch @matmul_dispatch_0::@...(%arg2[...], %arg3[...]) : ...
  stream.yield %4 : !stream.resource<...>
} => !stream.timepoint

// stream.timepoint.await 等待 timepoint 完成,取出结果
%2 = stream.timepoint.await %result_timepoint => %results : !stream.resource<...>

(2) resource —— 内存资源(带显式生命周期)

tensor(值语义)在 Stream 层变成 !stream.resource<...>(带大小),生命周期显式管理:

%1 = stream.tensor.import on(#hal.device.affinity<@__device_0>) %arg0 : !hal.buffer_view -> tensor<2x4xf32> in !stream.resource<external>{%0}

resource 有:分配(alloc)、持有(retain)、释放(release)、子视图(subview)、 瞬态(transient)。生命周期由 ARC(Automatic Reference Counting) pass 自动管理。

(3) affinity —— 设备亲和性

每个 op 标注 on(#hal.device.affinity<@__device_0>),表示在哪个设备上执行。 跨设备的 op 需要 stream.async.transfer 来传输数据。

3. 四个抽象层次(关键!)

Stream dialect 内部有从高到低的层次,编译时逐步下降:

层次 op 前缀 何时产生 说明
tensor stream.tensor.* ConvertToStreamPass 值语义张量(最接近 Flow)
async stream.async.* + stream.timepoint.* ScheduleExecutionPass 异步执行 + timepoint 同步
cmd stream.cmd.* 接近 HAL 命令缓冲(dispatch/copy/fill/flush)
resource stream.resource.* 全流程 内存资源生命周期

4. 核心 op(IR/StreamOps.td)

  • tensor 层:stream.tensor.import/export、stream.tensor.dispatch、stream.tensor.sizeof
  • async 层:stream.async.execute、stream.async.dispatch、stream.async.transfer、 stream.async.copy/fill/load/store、stream.async.barrier
  • timepoint:stream.timepoint.await/barrier/join/import/export/immediate
  • cmd 层:stream.cmd.dispatch/execute/copy/fill/flush/invalidate/serial/concurrent
  • resource:stream.resource.alloc/dealloca/size/retain/release/subview/transients
  • executable:stream.executable、stream.binding.subspan

5. 关键 pass(Transforms/ + Analysis/)

pass 文件 作用
ConvertToStreamPass ConvertToStream.cpp Flow → Stream(核心入口)
ScheduleExecutionPass ScheduleExecution.cpp 调度:图 → async.execute + timepoint
ScheduleConcurrencyPass ScheduleConcurrency.cpp 并发调度(并行 workgroup 重叠)
PropagateTimepointsPass PropagateTimepoints.cpp timepoint 传播(优化同步点)
ScheduleAllocationPass ScheduleAllocation.cpp 资源分配调度
AutomaticReferenceCountingPass AutomaticReferenceCounting.cpp ARC:自动引用计数管理资源生命周期
ElideTimepointsPass / ElideAsyncCopiesPass 同名 消除冗余 timepoint / async copy
ReuseAllocationsPass / RefineUsagePass 同名 内存复用 / 使用细化

Analysis/(调度前的分析):

  • Affinity.cpp —— 设备亲和性分析
  • Partitioning.cpp —— 分区分析
  • ResourceHazards.cpp / ResourceUsage.cpp —— 资源冲突 / 使用分析

6. IR 变换(阶段 2 已见,精简回顾)

// ConvertToStreamPass:Flow → Stream,tensor 变 stream.resource,标上 affinity
%7 = stream.tensor.dispatch on(#hal.device.affinity<@__device_0>) @matmul_dispatch_0::@...(%2, %5) : ...

// ScheduleExecutionPass:包进 async.execute,产生 timepoint
%results, %result_timepoint = stream.async.execute ... { ... } => !stream.timepoint
%2 = stream.timepoint.await %result_timepoint => %results : !stream.resource<...>

7. 与 TVM 0.6 对照

Stream 概念 TVM 0.6 说明
timepoint / async.execute 无直接对应 TVM 的异步主要在 runtime(线程池/stream),不在编译期 IR 里显式建模
resource 生命周期 无(TVM 的 buffer 生命周期由 runtime 管) IREE 在编译期显式建模并 ARC
affinity device 注解 类似但 IREE 更显式
scheduling 无(TVM 是同步图 + runtime 调度) IREE 把调度变成 IR 变换

核心差异:TVM 把「图是同步的、异步是 runtime 的事」;IREE 把「异步调度」提升为编译期的显式 IR 层, 可以针对多设备做静态调度优化。这就是为什么 IREE 在多设备/异构场景更强。

8. 源码阅读路径

src/iree/compiler/src/iree/compiler/Dialect/Stream/
├── IR/StreamOps.td            # op 定义(先读,认识 tensor/async/cmd/resource 四层)
├── Analysis/                  # Affinity / Partitioning / ResourceHazards / ResourceUsage
├── Transforms/ConvertToStream.cpp      # Flow → Stream
├── Transforms/ScheduleExecution.cpp    # 异步调度(核心)
├── Transforms/PropagateTimepoints.cpp  # timepoint 优化
└── Transforms/AutomaticReferenceCounting.cpp  # 资源生命周期 ARC

学习建议:先读 ScheduleExecution.cpp 理解「怎么从同步图变异步」, 再读 PropagateTimepoints.cpp 理解「timepoint 怎么优化」, 最后读 AutomaticReferenceCounting.cpp 理解「资源生命周期怎么管」。