Skip to content

[Bug] PTODSL-vmi, vci:DESC 忽略 base、compact 隔点取样、小 VL group_store layout、i8 小 VL Simulator 拒 S #1482

Description

@chenben09

Component

PTO Dialect / ODS (include/PTO/IR)

Description

A5/VPTO 测试独立 pto.vmi.vci(无 mask、无下游 DUT)时,compile 通过后 run 阶段出现四类失败。契约见 docs/isa/vmi-isa/02-index-gen.md(dst[i]=base±i,group 按组重启)和 docs/isa/vmi-isa/00-architecture-overview.md(compact:L·bitwidth(T)<2048 时仅低 L 个逻辑 lane 有效)。

问题①:DESC 未按 base-i 生成
满物理 VL、base=0 时 ASC 常 PASS,DESC 常 FAIL。Golden:[0,-1,-2,…]。DUT:从物理 lane 数-1 降到 0(如 f16×128 为 [127,126,…,0])。忽略 base。i8×VL=256×G=1×DESC(base=127)相对 ISA 整体少 1。

问题②:逻辑 VL < 物理 VL 时按物理 iota 隔点取样
compact 的 size 小于该 dtype 一条 vreg 的 lane 数。ISA 要求逻辑 [0,1,…,size-1]。DUT 按满物理长度生成再隔 phys/size 取样。ASC 也会挂(lane0 对,后面步长错误)。

问题③:小 VL + group>1 触发 group_store layout 契约失败
vstore 降成 pto.vmi.group_store 后:值仍是 contiguous,store 要求 grouped,ensure_layout 无物化路径。五种 dtype、ASC/DESC 全挂,未比数值。VL=8 即使 group=1 也全部 VPTO emission 失败(与 ③ 的 group_store 文案不完全相同)。

问题④:i8 极小 VL Simulator abort
i8×VL∈{1,2,4}×G=1:pem_rvec_ooo.cc / RV_VMULS / type.S8,exit 134。同 VL 的 i16/i32/f16/f32×G=1 可过。

Reproduction (minimal)

关键 kernel:
@jit_kernel(name, params)
def kernel(out_ptr: pto.ptr(dtype, "gm")):
    out_ub = pto.castptr(pto.i64(0), pto.ptr(dtype, "ub"))
    if group == 1:
        idx = pto.vmi.vci(dtype(base), size=vl, order=order)
    else:
        idx = pto.vmi.vci(dtype(base), size=vl, order=order, group=group)
    pto.vmi.vstore(idx, out_ub, pto.const(0, dtype=pto.index))
    pto.set_flag("V", "MTE3", event_id=0)
    pto.wait_flag("V", "MTE3", event_id=0)
    pto.mte_ub_gm(out_ub, out_ptr, nbytes, nburst=(1, 0, 0))

Expected behavior

DESC:dst[i]=base-i(group>1 时组内 j 同样从 base 重启)。
compact:写出 size 个逻辑 lane,ASC 为 base+i(i=0..size-1),不是物理满长隔点。
group>1 小 VL:能 lowering,或不支持则编译期明确拒绝,而不是 group_store LAYOUT-CONTRACT。
i8 小 VL:Simulator 能跑,或契约明确不支持。

Actual behavior / error logs

问题①(DESC,f16 vl128 g=1 base=0):
失配[0] A=np.float16(127.0) G=np.float64(0.0)
[1] A=126 G=-1  … 100% mismatch
代表:vci_f16_vl128_g1_a128_n_nomask_t02
对照 PASS:vci_f16_vl128_g1_a128_n_nomask_t01(ASC)

问题②(compact ASC,f16 vl64 g=1 base=0):
失配[1] A=2 G=1;[2] A=4 G=2(lane0 均为 0)
代表:vci_f16_vl64_g1_a64_n_nomask_t01
      vci_i16_vl64_g1_a64_n_nomask_t01
      vci_i8_vl64_g1_a64_n_nomask_t01
      vci_i8_vl128_g1_a128_n_nomask_t01

问题③(group>1 小 VL):
VMI-LAYOUT-CONTRACT: pto.vmi.group_store operand #0 has type
  !pto.vmi.vreg<2xi32, contiguous> but requires
  !pto.vmi.vreg<2xi32, num_groups=2, slots=1>
代表:vci_*_vl{2,4,8}_g{2,4,8}_*_t01/t02(五 dtype 全挂)
VL=8 g=1:五种 dtype 均为 VPTO emission pipeline failed

问题④(i8 极小 VL g=1):
RVecUop Failed to find VALU type (Unsupported Instr/Type).
instr.name=RV_VMULS, type.S8
代表:vci_i8_vl{1,2,4}_g1_*_t01/t02

Git commit

75e4a22

Host platform

Linux (aarch64)

Target Ascend arch (if relevant)

a5

PTOAS build level (if relevant)

None

Activity

  1. added
    bugSomething isn't working
    QAIssues from the QA team
    on Sep 7, 2026
  2. changed the title [-][Bug] PTODSL-vmi,独立 vci:DESC 忽略 base、compact 隔点取样、小 VL group_store layout、i8 小 VL Simulator 拒 S[/-] [+][Bug] PTODSL-vmi, vci:DESC 忽略 base、compact 隔点取样、小 VL group_store layout、i8 小 VL Simulator 拒 S[/+] on Sep 7, 2026
  3. liuzidi commented on Oct 9, 2026

    @liuzidi
    Collaborator

    在 hw-native-sys/master = 1b36b6f58(2026-10-08,比提报时的 75e4a224 新若干 vmi/iota 修复)上逐条复现,结论如下:①(DESC 忽略 base)和 ③ 的小 VL 部分仍然存在;② 已由主线修复;④ 仍可达,但根因在 PTOAS 侧(多发了一条 i8 的 vmuls)。

    复现方式:按 issue 里的 kernel 写 PTODSL(pto.vmi.vci → pto.vmi.vstore → mte_ub_gm),经完整 ptoas --pto-arch=a5 --pto-backend=vpto 管线,用 --emit-vpto-llvm-ir 看最终发射结果。硬件语义对照 A5 参考实现 pto-isa/include/pto/npu/a5/Tci.hpp。


    ① DESC 忽略 base —— 确认,仍存在

    f16 VL=128、base=0、order="DESC",最终 LLVM IR:

    %9 = call <128 x half> @llvm.hivm.vci.v128f16(half 0xH0000, i32 1)
    

    base 原样透传、无补偿。对照 Tci.hpp 的 descending==1 分支:它要生成 dst[j] = S - j,传入的标量是 s - i*vl_size,其中 s = S - vl_size + 1。这只有在硬件 DEC 斜坡为 (scalar + VL - 1) - k(标量指斜坡上端,不是第一个元素)时才成立;PTOAS 当前假设的是 scalar - k。

    该模型可精确复现报告中的两个现象:

    场景 PTOAS 传入标量 硬件实际 ISA 要求 报告现象
    f16 VL=128 base=0 0 127-k -k [127,126,…,0],base 被忽略
    i8 VL=256 base=127 127 382-k ≡ 126-k (mod 256) 127-k “整体少 1”

    受影响发出点(携带用户 base 且 {order="DESC"}):

    • lib/PTO/Transforms/VMIToVPTO/VMIToVPTOPatternInternals0.cpp:712(createIotaContiguousChunk,经 createIotaChunkBase:664)
    • lib/PTO/Transforms/VMIToVPTO/VMIToVPTOPatternInternals7.cpp:247(DESC shuffle/vselr 索引向量)

    另外 f16 VL=128 group=2 DESC 也走了这条坏路径:发出 vci(0,DESC) 后 vadds +64 → 物理 [191…64],而契约要求组内为 -j。整数 group DESC 走的是显式 vci(0,ASC) + vsub,反而不受影响。

    修法方向:DESC 时传 chunk_base - (VL - 1)(VL 取该 pto.vci 结果的物理 lane 数),或统一改走 ASC + 显式取负。注意这两处也编码了同一错误假设,需一起改:docs/designs/vmi-implementation-manual.md(“contiguous full-chunk direct path: chunk_base = base +/- c * lanes_per_part”)和 test/lit/vmi_new/vmi_to_vpto_iota.pto 的 DESC CHECK 行(如 vmi_to_vpto_iota_i32_desc 断言 pto.vci %arg0 {order="DESC"})。

    ② compact 隔点取样 —— 无法复现,已被主线修复

    master 上改为在 lane-strided 载波内就地生成斜坡。f16 VL=64(物理 128):

    %9  = call <128 x half> @llvm.hivm.vci.v128f16(half 0xH0000, i32 0)
    %11 = call <128 x half> @llvm.hivm.vmuls.s.x.v128f16(%9, half 0xH3800, ...)  ; ×0.5
    %12 = call <128 x half> @llvm.hivm.vadds.s.x.v128f16(%11, half 0xH0000, ...)
    call void @llvm.hivm.vstsx1.v128f16(<128 x half> %12, ..., i32 7, ...)
    

    i16 VL=64 用 vshrs >>1、i8 VL=64 用 >>2、i8 VL=128 用 >>1。斜坡已按 physVL/L 缩放,隔点取样后正好是 0,1,2,…。对应的修复是 65ea22142 fix(vmi): correct lane-strided iota lowering for float and integer types(2026-09-20,修 #1411),晚于本 issue 提报时间(09-07);修复前的形态(vci(0) 不缩放 + 隔 2 取样)正好产生 [0,2,4,…],与报告一致。

    ③ 小 VL —— 确认(L ∈ {2,4,8} 且 group=1,五种 dtype 全挂)

    完整 ptoas 管线结果:

    VL 结果
    1 通过
    2、4、8 VMI-RESIDUAL-OP: failed to convert all VMI ops/types to VPTO → VPTO emission pipeline failed.
    64、128、256 通过

    机制是 layout assignment 把小连续向量按 lane 数判成 group-slots 布局:

    %3 = pto.vmi.iota %2 : f16 -> !pto.vmi.vreg<8xf16, #pto.vmi.layout<num_groups = 8, slots = 8>>
    pto.vmi.group_store %3, %1[%4], %c1 {num_groups = 8 : i64} : ...
    

    而 VMI→VPTO 没有 num_groups = L (L>1), slots = 8 的 iota/group_store lowering;num_groups = 1 会归一到可用路径,所以 VL=1 能过。报告原文是旧版 VMI-LAYOUT-CONTRACT … requires num_groups=2, slots=1;现在 assignment 给的是 slots=8,文案变了但形状依旧无法 lowering。

    报告中的 group>1 变体(vl∈{2,4,8} × g∈{2,4,8}、五种 dtype、显式 contiguous layout、强制 group_store)在 master 上已无法复现,会降到 vdup + PAT_VL* 存储 —— 这部分看起来在提报之后已被修掉。

    ④ i8 小 VL Simulator abort —— 仍可达,但根因在 PTOAS 侧

    在 i8 VL=1(目前唯一还能编译过的小 i8 形状)上,VPTO IR 为:

    %2 = pto.vci %c0_i8 : i8 -> !pto.vreg<256xi8>
    %4 = pto.vmuls %2, %c1_i8, %1 : !pto.vreg<256xi8>, i8, !pto.mask<b8> -> !pto.vreg<256xi8>
    %5 = pto.vadds %4, %c0_i8, %1 : ...
    pto.vsts %5, %0[%c0], %3 {dist = "1PT_B8"} : ...
    

    最终 IR:<256 x i8> @llvm.hivm.vmuls.s.x.v256i8(..., i8 1, ...) —— 对 i8(S8) 发出 vmuls,CA model 无对应 VALU 类型,故 exit 134 / RV_VMULS, type.S8。乘数是空操作 1(索引按 factor==1 缩放),可以省掉该乘法,或改走 i8 VL≥64 已在用的整数 vshrs 路径(那些 VL 发的是 vshrs.u.x,不含 vmuls)。发出点:VMIToVPTOPatternInternals0.cpp:1141(createIotaDeinterleavedChunk),另见 VMIToVPTOMaskInternals.cpp:780。


    覆盖缺口

    仓库内该 op 唯一的运行时用例 test/vpto/cases/micro-op/dsa-sfu/vci/ 只覆盖 ASC + 满物理长度 + group=1 + 无 mask,即全部会通过的配置;DESC、compact、group、小 VL 均无覆盖,因此 ①③④ 长期未被发现。

    验证程度说明

    ①②③④ 均在本地 ptoas(--pto-arch=a5 --pto-backend=vpto,ptoas 0.67)上直接复现到编译/发射结果,其中 ①③ 是编译/发射期确定结论。本环境为 x86 主机、未执行 a5 仿真器,故运行时现象(② 的数值比对、④ 的 abort)是按发射出的 IR 推断的,未在仿真器上实测;如需仿真器实测请告知。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

QAIssues from the QA teambugSomething isn't workingvmi

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions