问题描述
TSEL(dst, mask, trueSrc)(dst = mask ? trueSrc : dst_prior,false-source 就是 dst 自身)经工具链
lower 成一条 B.IOT:两个 tile 源(mask、trueSrc)+ ->dst 就地。官方发布版 emulator 却按
显式三源建模,于是 validate 侧要求首拍 dsts.empty()、execute 侧读 srcTile[2] → 一条 TSEL 即崩。
复现步骤 / 触发条件
复现基线
最简复现探针
test/kernel/quant/dynamic_mx_quant/src/tsel_inplace_probe.cpp(Makefile TYPE=TSEL_INPLACE_PROBE)——
整个 kernel 只有一条 TSEL,不牵涉 dynamic_mx_quant 的任何 scale 计算:
tile_u16 x, mask, k;
TEXPANDS(x, (uint16_t)0xABCD); // 就地 false-source 种子
TEXPANDS(mask, (uint16_t)1); // 全真谓词
TEXPANDS(k, (uint16_t)0x1234); // true-source 常量
TSEL(x, mask, k); // 就地: x = mask ? k : x_prior
TSTORE(gy, x);
实测报错( bin/gfrun @ 63dbb5a2)
gfrun: illegal instruction: ASSERTION FAILED:
inst->srcs.size() == 3 && inst->dsts.empty() &&
IsCompatibleLogicalTile(inst->srcs[1], ...) &&
IsCompatibleDataTile(inst->srcs[2], ...) &&
"select first B.IOT requires mask then true/source Tile"
, func ValidateCompareSelectTepl, file emulator/engine/AccumulateBlockInfo.cpp:383
同一条 ELF 在带修复的 emulator 上 R2 = 0 跑通(12 block / 61 inst)——隔离出缺陷在
emulator 的 TSEL 建模层,非 kernel、非 ISA 编码。
附加信息
Ground truth:工具链实发的 TSEL lowering
.../tileop-api/jcore/template_asm.hpp TSEL(dst,src0,src1) 汇编体 = 一条 B.IOT:
BSTART.TEPL 0, 26, %D1
B.DIM %2, 0, ->lb0 ; validCol
B.DIM %3, 0, ->lb1 ; validRow
B.DIM zero, %c4, ->lb2 ; physicalCol = Cols
B.IOT %5, %6, mask=1111, last, ->%0<%Z7> ; %5=mask, %6=trueSrc, ->%0=dst 兼就地 false-source
两个源 tile(mask、trueSrc)+ dst 就地兼隐式 false-source;无第二拍、无独立第三源。 与 TSELS
(scalar false-source)同族形态,属 ISA 固有 lowering。
emulator 现状(63dbb5a2,两侧都假设显式三源)
- validate
AccumulateBlockInfo.cpp:383 ValidateCompareSelectTepl 首拍分支强制
inst->srcs.size()==3 && inst->dsts.empty()(首拍不许带 dst、要独立第三源)→ 工具链单拍带 dst(->%0) 撞断言。
- execute
TEPLEngine.cpp:1118 ExecuteTSEL 在 :1126 无条件读 block->srcTile[2](假设三源)→
工具链只 2 源 → 越界(validate 放宽后才会暴露)。
按最新 PTO ASL 复核后的结论
需要修正本 issue 当前的根因判断:按最新 PTO-ISA/pto-spec/main@8f8244d3ce71174a048f852625ca6138296b6dcc,这里复现的“单条 B.IOT + destination 就地作为 false-source”不是 TSEL 的合法 canonical lowering。当前现象的真实原因是 compiler/用例生成的 TSEL bundle 不符合最新 PTO spec contract,模型在 validate 阶段拒绝该 bundle 是符合规范的 fail-closed 行为。
规范原文见:
ASL 中的 canonical binding 原文
TSEL.asl 的 contract.block_composition 原文要求:
BSTART.VEC TSEL, DataType
B.DATR PadValue (optional)
B.DIM LB0=ValidCol
B.DIM LB1=ValidRow (optional)
B.DIM LB2=Col (optional)
B.IOT Predicate, SrcTrue, mask=PE_MASK
B.IOT SrcFalse, mask=PE_MASK, <last>, ->DstTile<TSize>
BSTOP
同一个 ASL contract 的 legality 原文是:
Exactly two ordered Local B.IOT bindings are required.
The first supplies packed Predicate and SrcTrue without Last or a destination;
the second supplies SrcFalse and one new terminating destination.
B.IOR, B.IOS, and additional bindings are illegal.
ASL 对 operand role 的原文定义是:
destination0 | new Local numeric destination
source0 | packed one-bit Local predicate mask
source1 | persistent Local source selected by one
source2 | persistent Local source selected by zero
因此 TSEL 的标准语义是:
predicate bit = 1 -> SrcTrue
predicate bit = 0 -> SrcFalse
而不是:
predicate bit = 0 -> implicit destination prior
ASL 的 state/ordering contract 还要求 source snapshot 先于 destination write,但这表示 source/destination alias 时必须观察旧值,并不表示可以省略显式的 SrcFalse binding:
Predicate bits and both data payloads are snapshotted before the first destination write,
so equal sources and source/destination aliases observe read-old values.
当前 issue 复现违反了哪些字段
Issue 中给出的 lowering 是:
B.IOT %5, %6, mask=1111, last, ->%0<%Z7>
它相当于把 Predicate + SrcTrue + Last + Destination 放在一条 B.IOT 中,和最新 ASL 有以下冲突:
- 第一条 B.IOT 不允许带
Last;
- 第一条 B.IOT 不允许带 destination;
- 缺少第二条 B.IOT 提供
SrcFalse;
- destination 被错误地当成了隐式 false-source;
- ASL 要求 destination 是新的 Local numeric destination,而不是用 destination prior 替代
source2。
所以 issue 中“工具链实发的单拍 B.IOT 是 ISA 固有 lowering”这一判断,与当前最新 ASL 不一致。旧版本工具链、旧 compiler lowering 或旧 benchmark ELF 的运行成功,不能作为 0.58.4 contract 的依据;permissive emulator 能运行 malformed bundle 也不能证明该 bundle 合法。
模型代码与规范的对应关系
当前模型的 TSEL validate 逻辑已经按上述两段 binding 处理:
- 第一拍要求
Predicate + SrcTrue,无 destination;
- 第二拍要求
SrcFalse,并分配 destination;
- execute 路径使用三个 source roles:mask、true source、false source。
对应代码:
当前首拍触发的 assertion:
select first B.IOT requires mask then true/source Tile
对于 issue 给出的非 canonical single-B.IOT ELF,属于预期的 legality rejection,不应通过放宽 dsts.empty() 或将 dstTile[0] 自动当作 srcTile[2] 来绕过。那样会让模型接受 ASL 明确禁止的 binding schema。
应该怎样修复
compiler/用例应按最新 ASL 重新生成 ELF,形式应为:
BSTART.VEC TSEL, DataType
B.DIM LB0=ValidCol
B.DIM LB1=ValidRow
B.DIM LB2=Col
B.IOT Predicate, SrcTrue, mask=PE_MASK
B.IOT SrcFalse, mask=PE_MASK, last, ->DstTile<TSize>
BSTOP
如果高级 API 仍然提供:
并希望用户看到“就地更新”,compiler 应在内部将旧的 x 作为第二条 B.IOT 的 SrcFalse,生成新的 destination binding,再更新后续 x 的 tile binding;不能把旧 destination 隐式塞进第一条 B.IOT。
请 compiler/用例侧基于最新 pto-spec 重新生成 tsel_inplace_probe,并提供 canonical two-B.IOT ELF。若 canonical ELF 在模型上仍失败,再单独建立模型修复;当前 issue 中的 single-B.IOT 复现不应作为模型放宽依据。
归属结论
根因:compiler / benchmark ELF lowering 不符合最新 PTO TSEL ASL
模型:当前 fail-closed 行为符合最新 TSEL binding contract
修复侧:compiler/用例生成链
问题描述
TSEL(dst, mask, trueSrc)(dst = mask ? trueSrc : dst_prior,false-source 就是 dst 自身)经工具链lower 成一条
B.IOT:两个 tile 源(mask、trueSrc)+->dst就地。官方发布版 emulator 却按显式三源建模,于是 validate 侧要求首拍
dsts.empty()、execute 侧读srcTile[2]→ 一条 TSEL 即崩。复现步骤 / 触发条件
复现基线
最简复现探针
test/kernel/quant/dynamic_mx_quant/src/tsel_inplace_probe.cpp(MakefileTYPE=TSEL_INPLACE_PROBE)——整个 kernel 只有一条 TSEL,不牵涉 dynamic_mx_quant 的任何 scale 计算:
实测报错(
bin/gfrun@ 63dbb5a2)同一条 ELF 在带修复的 emulator 上
R2 = 0跑通(12 block / 61 inst)——隔离出缺陷在emulator 的 TSEL 建模层,非 kernel、非 ISA 编码。
附加信息
Ground truth:工具链实发的 TSEL lowering
.../tileop-api/jcore/template_asm.hppTSEL(dst,src0,src1)汇编体 = 一条B.IOT:两个源 tile(mask、trueSrc)+ dst 就地兼隐式 false-source;无第二拍、无独立第三源。 与
TSELS(scalar false-source)同族形态,属 ISA 固有 lowering。
emulator 现状(63dbb5a2,两侧都假设显式三源)
AccumulateBlockInfo.cpp:383ValidateCompareSelectTepl首拍分支强制inst->srcs.size()==3 && inst->dsts.empty()(首拍不许带 dst、要独立第三源)→ 工具链单拍带 dst(->%0) 撞断言。TEPLEngine.cpp:1118ExecuteTSEL在:1126无条件读block->srcTile[2](假设三源)→工具链只 2 源 → 越界(validate 放宽后才会暴露)。
按最新 PTO ASL 复核后的结论
需要修正本 issue 当前的根因判断:按最新
PTO-ISA/pto-spec/main@8f8244d3ce71174a048f852625ca6138296b6dcc,这里复现的“单条B.IOT+ destination 就地作为 false-source”不是 TSEL 的合法 canonical lowering。当前现象的真实原因是 compiler/用例生成的 TSEL bundle 不符合最新 PTO spec contract,模型在 validate 阶段拒绝该 bundle 是符合规范的 fail-closed 行为。规范原文见:
ASL 中的 canonical binding 原文
TSEL.asl的contract.block_composition原文要求:同一个 ASL contract 的 legality 原文是:
ASL 对 operand role 的原文定义是:
因此 TSEL 的标准语义是:
而不是:
ASL 的 state/ordering contract 还要求 source snapshot 先于 destination write,但这表示 source/destination alias 时必须观察旧值,并不表示可以省略显式的
SrcFalsebinding:当前 issue 复现违反了哪些字段
Issue 中给出的 lowering 是:
它相当于把
Predicate + SrcTrue + Last + Destination放在一条 B.IOT 中,和最新 ASL 有以下冲突:Last;SrcFalse;source2。所以 issue 中“工具链实发的单拍 B.IOT 是 ISA 固有 lowering”这一判断,与当前最新 ASL 不一致。旧版本工具链、旧 compiler lowering 或旧 benchmark ELF 的运行成功,不能作为 0.58.4 contract 的依据;permissive emulator 能运行 malformed bundle 也不能证明该 bundle 合法。
模型代码与规范的对应关系
当前模型的 TSEL validate 逻辑已经按上述两段 binding 处理:
Predicate + SrcTrue,无 destination;SrcFalse,并分配 destination;对应代码:
ValidateCompareSelectTeplExecuteTSEL当前首拍触发的 assertion:
对于 issue 给出的非 canonical single-B.IOT ELF,属于预期的 legality rejection,不应通过放宽
dsts.empty()或将dstTile[0]自动当作srcTile[2]来绕过。那样会让模型接受 ASL 明确禁止的 binding schema。应该怎样修复
compiler/用例应按最新 ASL 重新生成 ELF,形式应为:
如果高级 API 仍然提供:
TSEL(x, mask, trueSrc)并希望用户看到“就地更新”,compiler 应在内部将旧的
x作为第二条 B.IOT 的SrcFalse,生成新的 destination binding,再更新后续x的 tile binding;不能把旧 destination 隐式塞进第一条 B.IOT。请 compiler/用例侧基于最新
pto-spec重新生成tsel_inplace_probe,并提供 canonical two-B.IOT ELF。若 canonical ELF 在模型上仍失败,再单独建立模型修复;当前 issue 中的 single-B.IOT 复现不应作为模型放宽依据。归属结论