Summary
The QSMLA operator in SuperNPUBench is blocked at two layers after #104 (the pto-spec #257 adaptation), with no kernel form able to both compile and run:
- Legacy usage (Shared B declared
[kTk, kTd] + transpose_b()) → compile-time static_assert failures at template_asm.hpp:3898/3911 (effective-K mismatch / cooperative D shape mismatch).
- #257-adapted usage (QK path: no
transpose_b; PV path: transpose_b) → compiles clean, but gfrun aborts at SuperScalarModel emulator/SoftCore.cpp:2245 (ADR-0100 cooperative TMATMUL check).
This is filed here (TileOP-API) per maintainers' tracking preference, but the remaining defect itself lives in SuperScalarModel — details below.
Reproduction (QSMLA, 4-PE HIF8)
Verified versions (2026-09-10):
| Component |
Version |
| Linx-TileOP-API |
linx @ 748ac69 (includes #104 01d62c4, #105) |
| SuperScalarModel |
main @ db88b82 (ops-20260908 baseline, 2026-09-10 guard report) |
| llvm-project |
dev-llvm15_56 @ 10abd6e |
| SuperNPUBench |
ops-20260910 (2c107e9, QSMLA kernel still on legacy usage) |
Cases: swa_small / csa_small / ori_sparse_small (test/solution/quant_sparse_flash_mla, IMPL=*_tadd_4pe, QSMLA_DTYPE=HIF8).
Layer 1: compile (expected, this is the migration)
QSMLA's K staging is tileKMatrix = SharedMatrixRight<kvdtype, kTk=32, kTd=64> — one KV token per row, D contiguous, i.e. the physical [N,K] form. Under the new contract that is TransB=0, so the legacy transpose_b() calls no longer compile (static_asserts above). Layer 1 is working as designed per #104; the QSMLA kernel adaptation is:
- QK (
Q @ K^T): remove transpose_b() — physical [32,64] declares [N,K].
- PV (
P @ V): add transpose_b() — the same physical [32,64] layout is [K,N] for the PV math (N contiguous).
Layer 2: gfrun rejects the adapted form — the actual defect (SuperScalarModel)
gfrun at db88b82 still consumes TransB with the pre-#255 math-transpose-flag semantics — the exact opposite of the post-#104 contract:
| Physical Shared B layout |
Math B |
TileOP #104 expects |
gfrun db88b82 expects |
[N,K] (K contiguous) |
[K,N] |
TransB=0 |
TransB=1 |
[K,N] (N contiguous) |
[K,N] |
TransB=1 |
TransB=0 |
Both consumption sites in emulator/SoftCore.cpp use the old reading:
- validation (
:2218): rightPhysicalRows = transB ? n : k — under #257 this must be transB ? k : n;
- execution (
:2346): LoadSharedMatrix(..., block->transB) — must be !block->transB (TransB=0 means the physical source is the transposed store, so the read must transpose).
Notably, TransA in the same function IS aligned with #257 (leftPhysicalRows = transA ? k : expectedLeftRows) — only TransB is inverted, which looks like a missed update when #255/#257 landed, not an intentional divergence.
This also explains why #103's verification did not catch it: the reported checks ("emits LB1=32(N), LB2=64(K) for B declared <32,64>; compiles 0 error") stop at the compile/emission level. A runtime cross-check (compile with #104, then run gfrun) would have exposed the mismatch immediately.
Verified fix (2-line flip in SuperScalarModel)
--- a/emulator/SoftCore.cpp
- const size_t rightPhysicalRows = block->transB ? n : k;
- const size_t rightPhysicalCols = block->transB ? k : n;
+ /* pto-spec #257: TransB describes the PHYSICAL stored RowMajor shape.
+ * TransB=0 stores [N, K] (rows=N); TransB=1 stores [K, N] (rows=K). */
+ const size_t rightPhysicalRows = block->transB ? k : n;
+ const size_t rightPhysicalCols = block->transB ? n : k;
...
- std::vector<uint64_t> right = LoadSharedMatrix(rightSharedId, rightType,
- k, n, requestRightSubview, block->transB);
+ std::vector<uint64_t> right = LoadSharedMatrix(rightSharedId, rightType,
+ k, n, requestRightSubview, !block->transB);
And the QSMLA kernel adaptation (SuperNPUBench, for reference):
--- a/.../quant_sparse_flash_mla.hpp
- TMATMUL(tScoreCube, tQShared, tKShared,
- fixp::keep_acc().transpose_b()); // QK, x4 sites
+ TMATMUL(tScoreCube, tQShared, tKShared,
+ fixp::keep_acc());
...
- TMATMUL(tPVCube, tPShared, tVShared,
- fixp::keep_acc()); // PV
+ TMATMUL(tPVCube, tPShared, tVShared,
+ fixp::keep_acc().transpose_b());
Verification
With both patches applied, all three QSMLA cases pass gfrun at 100% with results bitwise identical to the pre-#104 baseline:
| Case |
Result |
max_abs |
| swa_small |
32768/32768 (100%) |
0.004920 |
| csa_small |
32768/32768 (100%) |
0.004677 |
| ori_sparse_small |
32768/32768 (100%) |
0.009071 |
Bitwise-identical max_abs across the semantic change confirms the flip direction is correct (a wrong direction would transpose B the wrong way and fail broadly). Note gfsim's TimingSim does not consume transB numerically, but its embedded functional verification hits the same assert, so gfsim must be rebuilt with the fix.
Ask
References
Summary
The QSMLA operator in SuperNPUBench is blocked at two layers after #104 (the pto-spec #257 adaptation), with no kernel form able to both compile and run:
[kTk, kTd]+transpose_b()) → compile-timestatic_assertfailures attemplate_asm.hpp:3898/3911(effective-K mismatch / cooperative D shape mismatch).transpose_b; PV path:transpose_b) → compiles clean, butgfrunaborts atSuperScalarModel emulator/SoftCore.cpp:2245(ADR-0100 cooperative TMATMUL check).This is filed here (TileOP-API) per maintainers' tracking preference, but the remaining defect itself lives in SuperScalarModel — details below.
Reproduction (QSMLA, 4-PE HIF8)
Verified versions (2026-09-10):
748ac69(includes #10401d62c4, #105)db88b82(ops-20260908 baseline, 2026-09-10 guard report)10abd6eops-20260910(2c107e9, QSMLA kernel still on legacy usage)Cases:
swa_small/csa_small/ori_sparse_small(test/solution/quant_sparse_flash_mla,IMPL=*_tadd_4pe,QSMLA_DTYPE=HIF8).Layer 1: compile (expected, this is the migration)
QSMLA's K staging is
tileKMatrix = SharedMatrixRight<kvdtype, kTk=32, kTd=64>— one KV token per row, D contiguous, i.e. the physical[N,K]form. Under the new contract that isTransB=0, so the legacytranspose_b()calls no longer compile (static_asserts above). Layer 1 is working as designed per #104; the QSMLA kernel adaptation is:Q @ K^T): removetranspose_b()— physical[32,64]declares[N,K].P @ V): addtranspose_b()— the same physical[32,64]layout is[K,N]for the PV math (N contiguous).Layer 2: gfrun rejects the adapted form — the actual defect (SuperScalarModel)
gfrunatdb88b82still consumes TransB with the pre-#255 math-transpose-flag semantics — the exact opposite of the post-#104 contract:db88b82expects[N,K](K contiguous)[K,N][K,N](N contiguous)[K,N]Both consumption sites in
emulator/SoftCore.cppuse the old reading::2218):rightPhysicalRows = transB ? n : k— under #257 this must betransB ? k : n;:2346):LoadSharedMatrix(..., block->transB)— must be!block->transB(TransB=0 means the physical source is the transposed store, so the read must transpose).Notably, TransA in the same function IS aligned with #257 (
leftPhysicalRows = transA ? k : expectedLeftRows) — only TransB is inverted, which looks like a missed update when #255/#257 landed, not an intentional divergence.This also explains why #103's verification did not catch it: the reported checks ("emits LB1=32(N), LB2=64(K) for B declared <32,64>; compiles 0 error") stop at the compile/emission level. A runtime cross-check (compile with #104, then run gfrun) would have exposed the mismatch immediately.
Verified fix (2-line flip in SuperScalarModel)
And the QSMLA kernel adaptation (SuperNPUBench, for reference):
Verification
With both patches applied, all three QSMLA cases pass gfrun at 100% with results bitwise identical to the pre-#104 baseline:
Bitwise-identical max_abs across the semantic change confirms the flip direction is correct (a wrong direction would transpose B the wrong way and fail broadly). Note
gfsim's TimingSim does not consumetransBnumerically, but its embedded functional verification hits the same assert, so gfsim must be rebuilt with the fix.Ask
shared-cube-matrix.asl/BundleMatrixSharedBPrimarySchemaLegal) — no change requested here.ops-20260910) needs the kernel-side adaptation above.References
01d62c4, PR TileOP: Shared transposed MX ScaleA declares its physical shape (pto-spec #257) #105ad782cctest/solution/quant_sparse_flash_mla)