Repository navigation
T.Parallel 对接 PTO Roadmap #3
Description
1. 背景与目标
现状:
target="ascend"后端已合入 tile-ai 主线(tile-ai/tilelang#3308),PTO driver/codegen 已合入主线(tile-ai/tilelang#3310)。- VMI 语言面(
tl.vmi.*、VMI codegen)还没有合入主线,只在 fork 的 asc 分支(deepseek-ai/tilelang#250)。 T.Parallel对接 PTO 的完整实现目前只在 fork 侧:PR269(T.Parallel→PTO VMI 自动向量化)、PR262(控制流 + reduce_max/min/sum),均为 OPEN。- ST 验收套件已移植到 PTO-ISA/tilelang 的 pto-dev 分支:PR #2,
examples/ascend/t_parallel_st_suite/(21 个 SimtVFT.Parallelkernel + 21 个手写 PTODSL 对照版)。
目标:用户在 T.SimdVF(lanes=L) 内写标量并行的 T.Parallel 程序(element-wise、控制流、reduce),编译器自动向量化为 PTO VMI,经 PTOAS 编译在 Ascend 950 上正确运行。全部能力分若干 PR 合入 tile-ai 主线,每个 PR 的发起是一个路标。
分工原则:
| TileLang 侧 | PTOAS / 工具链侧 | |
|---|---|---|
| 职责 | 逻辑 lane 布局(E/P/Q/remaining、tail mask)、pass pipeline(Verify→Legalize→Vectorize)、VMI 指令生成、Fragment→slot 逻辑映射、UB 容量预算 | 物理寄存器拆分、mask 物理化、slot 物理实现(vreg 驻留 / slot 访存消除或保留对已绑定 backing 的读写决策)、依赖分析与同步插入(mem_bar)、CSE/LICM 等优化 |
2. Roadmap 总览
- M3 的主线 numeric 验收在 PTOAS P1(mem_bar,见 §5.1)合入后闭环;P1 需要修复后合入 PTOAS 主线。
3. 里程碑表
| 路标 | 上游 PR | 内容 | 特性 | 依赖 | 新增可打通 ST 用例(累计) |
|---|---|---|---|---|---|
| M1 | PR-1 | T.Parallel 核心向量化(含 VMI 语言面):tl.vmi.* builtin + VMI codegen、LayoutInference PTO 分支、Verify/Legalize/Vectorize pipeline、1D/2D 映射、E/P/Q tail mask、dtype/cast(含 FP8 转换矩阵)、element-wise |
F-EW | 无 | sv1(1/21) |
| M2 | PR-2 | 控制流:IfThenElse/Min/Max→Select、布尔表达式展开、vcmp/vsel、mask_and/or/not | F-CF | M1 | sv7、cf2、cf5、sp4(5/21) |
| M3 | PR-3 | direct tl.tileop.reduce(max/min/sum,单元素结果以 1PT 写回)、TopK example(index 全链路 int32) |
F-R1 | M2 + PTOAS P1 | 本路标不新增(sv9 还依赖 M4 的 F-FRAG) |
| M4 | PR-4 | Fragment/slot 存储:PlanPtoSlotStorage、layout_map contract、UB 容量预算、MergeUBAllocations 独占分配、slot_alloc/load/store codegen | F-FRAG | M1 + PTOAS P2 | sv2、sv3、sv5、sv6、sv8、sv9、cf1、cf3、cf4、cf6(15/21,其中 14 个用例的实现路径已明确,cf6 已纳入但实现路线待定,见 §8) |
| M5 | PR-5 | 间接访存与打包类型扩展:单侧 store predicate、uniform scatter 及通用 gather/scatter 向量化(F-GS)、ue8m0/fp4 位操作与 reinterpret(F-PACK)、stride-2/interleave 布局 | F-GS / F-PACK | M4 + PTOAS P3 | sv4、sp1、sp2、sp3、sp5、sp6(21/21) |
| M6 | PR-6 | reducer v2:PTO SIMD LayoutInference、ReducerPlanAndMaterialize 分支、finalize/seed/inactive-tail、RMSNorm numeric | F-R2 | M3 + M4;RMSNorm uniform 写回另依赖 M5 | ST 套件无直接消费者,由 RMSNorm 产品用例验收(21/21) |
PR-1 拆分方式(待定):当前倾向把 VMI 语言面并入 PR-1 一次合入;备选是 VMI 语言面单独先行一个 PR(review 工作量更小)。视社区反馈决定。
4. TileLang 侧工作分解
| # | 工作项 | 归入上游 PR |
|---|---|---|
| T0 | PR-1/PR-2 上游准备:基于 PTO-ISA/tilelang(fork 自 tile-ai main)整理发起分支,剔除 pto-dev 中 ci/example 等与 PTO/VMI 无关的改动(见 PTO-ISA/tilelang#1),拆分 PR-1/PR-2 分支并完成代码验证 | PR-1 / PR-2 |
| T1 | direct Reduce 收尾:device numeric 闭环(依赖 PTOAS P1;本地临时分支验证与主线验收分开记录) | PR-3 |
| T2 | direct Reduce 单元素 1PT 写回 + TopK 适配(E=161/L=64/P=192 尾部语义、index 全链路 int32) |
PR-3 |
| T3 | 控制流与 PR262 用例集成验证:CF 设备矩阵、TopK 重跑、vecadd/vintlv/dtype/SIMT/手写 VMI corpus | PR-2 / PR-3 |
| T4 | Fragment/slot 存储体系:通用 layout_map contract、PlanPtoSlotStorage、AutoSchedule 容量扣除、MergeUBAllocations、slot codegen | PR-4 |
| T5 | 间接访存与打包类型扩展:单侧 store predicate、uniform scatter、Verify 准入与 mask 消费、通用 gather/scatter 向量化、ue8m0/fp4 位操作与 reinterpret、stride-2/interleave 布局 | PR-5 |
| T6 | reducer 特性:PTO SIMD LayoutInference、ReducerPlanAndMaterialize PTO 分支、Vectorize reducer v2(sum/max/min、finalize、seed、inactive-tail accumulator) | PR-6 |
| T7 | 产品验证:RMSNorm compile/numeric、ST 套件 21 个 kernel 验收(见 §6) | PR-5 / PR-6 |
| T8 | 最终回归(PR269/PR262/dtype/SIMT/AscendC/手写 VMI/slot/reducer 全量)与上游 PR 拆分、review、合入 | PR-1 ~ PR-6 |
5. PTOAS 侧工作分解
| # | 工作项 | 阻塞关系 | 影响路标 |
|---|---|---|---|
| P1 | vecscope 内 V-pipe 依赖分析 + pto.mem_bar 自动插入(见 §5.1) |
阻塞 direct Reduce 的 numeric 验证 | M3 |
| P2 | slot 物理实现:vreg 驻留 / slot 访存消除或保留(对已绑定 backing 的读写)决策,liveness 与物理寄存器压力分析,逻辑向量→物理寄存器拆分;为保留的 UB 访问插 mem_bar | Fragment/slot 阶段配套 | M4 |
| P3 | gather/scatter 与打包类型的 PTO 侧指令配套;尚未完成方案分析与设计,待细化 | M5 配套 | M5 |
5.1 P1 问题说明(供 PTOAS 对接)
最小复现(TileLang 源码):
@T.prim_func
def main(A: T.Tensor((128,), "float32"), B: T.Tensor((1,), "float32")):
with T.Kernel(1):
a = T.alloc_shared((128,), "float32")
best = T.alloc_shared((1,), "float32")
T.copy(A, a)
with T.SimdVF(lanes=64):
for i in T.Parallel(128):
a[i] = a[i] * 2 # Parallel 写 UB(in-place)
T.reduce_max(a, best, dim=0, clear=True) # 同 region direct reduce 读同一 UB
T.copy(best, B)历史复现中 TileLang 生成的 PTODSL(关键片段,保留当时输出,不代表当前目标写回形态):
with pto.vecscope():
mask = pto.vmi.create_mask(64, size=64)
for q in range(0, 2, 1): # unit 循环:vload → vmul → vstore 写 UB
v = pto.vmi.vload(pto.addptr(a_ptr, q * 64), 0, size=64)
pto.vmi.vstore(pto.vmi.vmul(v, two, mask), pto.addptr(a_ptr, q * 64), 0, mask)
# ← unit 的 vstore 与 reduce 的 vload 之间没有任何保序
r0 = pto.vmi.vload(a_ptr, 0, size=64) # reduce:读同一 UB 地址
r1 = pto.vmi.vload(a_ptr, 64, size=64)
red = pto.vmi.vcmax(pto.vmi.vsel(mask, pto.vmi.vmax(r0, r1, mask), r0), mask)
pto.vmi.vstore(pto.vmi.vbrc(red, size=64), best_ptr, 0, pto.vmi.create_mask(1, size=64))问题:同一 SIMD VF 内部、同一 UB 地址的 vstore(Parallel 写)→ vload(reduce 读)RAW 依赖没有被保序,设备上 reduce 读到写入前的旧值。确定性复现(非竞态);9 用例数值矩阵 6 失败 3 通过;region 之后 copy-out 能读到新值(store 本身已落盘)。
需要 PTOAS 做的工作:在 VPTO 后端的 vecscope 内做 load/store 依赖分析,对真实依赖边按需插入 pto.mem_bar(向量 store/load 之间 RAW 用 VST_VLD、WAR 用 VLD_VST)。pto.mem_bar 是 vecscope 内合法原语(16 种 kind,TileOps a5 生产模板已有 vsts→vlds 同 tile 插 VST_VLD 的同构先例);注入单行 pto.mem_bar "VST_VLD" 后 9 用例矩阵 9/9 全部通过(手工注入的实验性验证,不代表 PTOAS 自动插入已落地)。同一机制还需按真实指令队列覆盖 direct Reduce 写回后的读取:vector store → vector load 使用 VST_VLD,vector store → auxiliary scalar load 使用 VST_LD,不能将两者混用。TileLang 侧不实现该分析。mem_bar 有运行时开销,应按需而非无条件插入。
6. 验收用例
- ST 套件(PTO-ISA/tilelang#2,
examples/ascend/t_parallel_st_suite/):kernels/21 个 kernel 全部纳入本期验收,验收路径为 SimdVF→PTO 向量化,暂不设置 opsim 性能门槛(kernels_ptodsl/21 个手写 PTODSL 版作正确性与性能参照)。 - 产品用例:TopK(非整除、tie-break、-inf 边界)、RMSNorm(compile + numeric);回归:vecadd/vintlv/PTO dtype/PTO SIMT/手写 VMI、AscendC 不回归。
6.1 逐 kernel 特性需求矩阵(21 个 kernel 逐个分析的结论)
| 特性 | 含义 | 归属路标 |
|---|---|---|
| F-EW | element-wise 基础向量化:连续 load/store、算术、broadcast、cast、tail mask | M1 |
| F-CF | lane-varying 控制流:IfThenElse/Min/Max→Select、mask 逻辑、条件更新 | M2 |
| F-R1 | direct reduce:reduce_max/min/sum 向量化、1PT 单元素写回与 TopK |
M3 |
| F-FRAG | Fragment/slot 存储:值驻留寄存器(KEEP-in-RF)、accumulator 跨循环驻留、layout_map/slot | M4 |
| F-GS | uniform scatter、store predicate 与通用 gather/scatter 间接访存 | M5 |
| F-PACK | 打包类型/特殊位操作:ue8m0/fp4、bit reinterpret、nibble 拆包 | M5 |
| F-R2 | reducer v2:reducer LayoutInference/materialize、finalize/seed、inactive-tail accumulator | M6 |
逐 kernel 需求("读/写"标注间接访存方向):
| 用例 | 计算模式 | F-EW | F-CF | F-R1 | F-FRAG | F-GS | F-PACK | 可满足路标 |
|---|---|---|---|---|---|---|---|---|
| sv1 | 流式 eltwise | ✓ | M1 | |||||
| sv2 | absmax scale + 广播应用(KEEP/reload 臂) | ✓ | ✓ | ✓ | M4 | |||
| sv3 | GEMV partial 累加(acc 跨 K 驻留;split 臂有 guard) | ✓ | ✓ | ✓ | M4 | |||
| sv4 | index gather + psum(w_ub[idx[i]] 读侧 gather) |
✓ | ✓ | ✓读 | M5 | |||
| sv5 | 小组 absmax scale(G16) | ✓ | ✓ | ✓ | M4 | |||
| sv6 | 中组 absmax(G32,warp 尺度驻留) | ✓ | ✓ | ✓ | M4 | |||
| sv7 | 大组 absmax(G128,partial 经 UB round-trip) | ✓ | ✓ | M2 | ||||
| sv8 | quant e2e:scale 广播回全网格 | ✓ | ✓ | ✓ | M4 | |||
| sv9 | topk e2e(reduce_max/min + kill 迭代) | ✓ | ✓ | ✓ | ✓ | M4 | ||
| cf1 | 阈值 kill(scores KEEP 跨 serial K) | ✓ | ✓ | ✓ | M4 | |||
| cf2 | 阈值 kill remat(条件写 shared,跨 region 依赖) | ✓ | ✓ | M2 | ||||
| cf3 | victim idx kill + lane index remat | ✓ | ✓ | ✓ | M4 | |||
| cf4 | 嵌套 if(clamp-hi/clamp-lo/fat-mul 三路 select;验收形态保留 Fragment staging) | ✓ | ✓ | ✓ | M4 | |||
| cf5 | 除法近零保护分支(fp32 div) | ✓ | ✓ | M2 | ||||
| cf6 | Newton 迭代分支(Parallel body 内嵌常数界 serial,路线待定,见 §8) | ✓ | ✓ | ✓(轻) | M4(路线待定) | |||
| sp1 | 双 payload 行 scatter(pos 间接行写) | ✓ | ✓ | ✓ | ✓写 | M5 | ||
| sp2 | 行 gather + 手动加权累加(acc KEEP) | ✓ | ✓ | ✓读 | M5 | |||
| sp3 | ue8m0 scale 位合成(reinterpret/shift) | ✓ | ✓ | M5 | ||||
| sp4 | pad 掩膜双分支拷贝(纯 vsel) | ✓ | ✓ | M2 | ||||
| sp5 | sideband/interleave 行 gather | ✓ | ✓读 | M5 | ||||
| sp6 | fp4 LUT 解包(lane-varying LUT gather + stride-2 写 + nibble 位操作) | ✓ | ✓读 | ✓ | M5 |
路标解锁汇总:
| 路标 | 新解锁用例 | 累计 |
|---|---|---|
| M1(F-EW) | sv1 | 1/21 |
| M2(+F-CF) | sv7、cf2、cf5、sp4 | 5/21 |
| M3(+F-R1) | —(sv9 同时依赖 M4 的 F-FRAG) | 5/21 |
| M4(+F-FRAG) | sv2、sv3、sv5、sv6、sv8、sv9、cf1、cf3、cf4、cf6(cf6 路线待定) | 15/21(14 个用例路径已明确,cf6 已纳入、路线待定) |
| M5(+F-GS/F-PACK) | sv4、sp1、sp2、sp3、sp5、sp6 | 21/21 |
| M6(+F-R2) | ST 套件无直接消费者(F-R2 由 RMSNorm 产品用例验收) | 21/21 |
7. 风险与依赖
- P1(mem_bar)需在 PR-3 发起前合入 PTOAS 主线,正由 PTOAS 团队开发;若滑期则 M3 顺延。
- PR-1 拆分方式需社区反馈:VMI 语言面并入首个 T.Parallel PR(当前倾向)vs 单独先行(备选)。
- TileLang 与 PTOAS 的版本配套:TileLang 跟随 PTOAS/CANN 主线演进,上游合入时需声明依赖的 PTOAS 最低版本(P1 落地后 M3 起有硬性版本依赖)。
- Fragment/slot 是新子系统,无现成迁移来源,工作量不确定性最高;且 M4 是 ST 用例解锁数最多(10 个)的路标,其延期对验收面影响最大。
- ST 套件验收需经 SimdVF→PTO 向量化路径:现有
kernels/为 SimtVF 形态,验收时需以 SimdVF 形态编译通过并数值正确。
8. 待定事项
- PR-1 拆分方式:VMI 并入首个 T.Parallel PR(倾向)还是单独先行(备选)——视社区反馈。
- CF6 内嵌串行循环的路线选择:cf6 的 Parallel 体内含常数界
T.serial(3)Newton 迭代。cf6 已纳入本期验收范围,以下路线均以覆盖 cf6 为前提:(1) Legalize 展开常数界串行循环,并合并分支臂内同位置写链;(2) Vectorize 直接支持 Parallel 体内 uniform 串行循环;(3) 验收层改写用例形态。待讨论确定。
Activity