Skip to content

TileOP: enforce the ISA capacity-derived TCVT geometry contract (#42) - #97

Merged
VV0003 merged 1 commit into
linxfrom
fix/tcvt-narrow-dst-col
Sep 8, 2026
Merged

TileOP: enforce the ISA capacity-derived TCVT geometry contract (#42)#97
VV0003 merged 1 commit into
linxfrom
fix/tcvt-narrow-dst-col

Conversation

@VV0003

@VV0003 VV0003 commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Fixes the TileOP side of #42 per the ISA verdict in the earlier comment.

What changed

The ordinary (non-CUBE) TCVT path required bitwise-identical C++ Rows/Cols between source and destination. That is stricter than the ISA:

PTO-TILE-TCVT legality: "Source and destination have equal Row, Col, ValidRow, and ValidCol. Their capacities and packing independently match their own DataTypes."

where Row/Col are the capacity-derived physical dimensions (DerivedTileRows = capacity*8 / (Col * elementBits), asl/tile/model/shape/rows-columns.asl) — not the C++ logical Rows/Cols — and each side's capacity independently matches its own DataType.

Why the old check was wrong for narrowing dtypes

bf16 → e8m0 [64,1]: the e8m0 destination's 64B payload is padded to the 128B minimum TSize, so its derived rows double (128) while the bf16 source stays at 64 — the emulator correctly rejects this per the ISA (that is the crash in #42). The ISA-legal encoding declares a wider physical column on both sides:

0 ""

0 ""

0 ""

1 "/usr/include/stdc-predef.h" 1 3 4

0 "" 2

1 ""

The old bitwise assertion made this legal encoding un-expressible (compounded by the reduce-chain pinning Col=1).

The fix

  • Replace Rows==Rows && Cols==Cols with the exact ISA condition: equal capacity-derived rows (computed from each side's StorageBytes — the B.IOT-encoded capacity — physical Col, and element bits), keeping ValidRow/ValidCol equality.
  • The old illegal form ([64,1]→[64,1] e8m0) now fails with a static_assert that names the ISA contract and points to the [Rows,2] pattern.
  • TCVT usage page documents the narrowing pattern (per the docs-sync convention).

Verification

Note: the kernel-side fix (dynamic_mx_quant) needs to declare the scale-chain tiles as [TileM, 2] with ValidCol=1 per the documented pattern; the model needs no change (its assertion is the correct ISA behavior).

The ordinary (non-CUBE) TCVT path required bitwise-identical C++
Rows/Cols between source and destination. That is stricter than the ISA:
PTO-TILE-TCVT legality requires equal Row, Col, ValidRow, ValidCol where
Row/Col are the capacity-derived physical dimensions
(DerivedTileRows = capacity*8 / (Col * elementBits),
asl/tile/model/shape/rows-columns.asl), and the capacities independently
match each side's own DataType.

For a narrowing conversion (bf16/fp32 -> e8m0 [Rows,1]) the 128B minimum
TSize doubles the destination's derived rows (e.g. 64 -> 128), so the
[Rows,1]/[Rows,1] encoding is illegal under the ISA and the emulator
rightly rejects it (issue #42). The ISA-legal encoding declares a wider
physical column on BOTH sides (e.g. [64,2] with ValidCol=1: bf16 256B ->
64 derived rows, e8m0 128B -> 64 derived rows).

This replaces the bitwise Rows/Cols assertion with the exact ISA
condition (equal capacity-derived rows), keeping ValidRow/ValidCol
equality, and documents the narrowing pattern in the TCVT usage page.

Verified:
- issue #42 chain (half->fp32->bf16->e8m0, all [64,2] VC=1) compiles;
  the final bundle emits lb2=2 with the e8m0 destination at 128B
  (DerivedTileRows 64 == source 64)
- the old [64,1]->[64,1] form is now rejected with a static_assert
  message that names the ISA contract and the [Rows,2] fix
- full gate 64/74 (11 failures identical on baseline); unittest 40/40
@VV0003
VV0003 merged commit 233ffdf into linx Sep 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant