Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## Measured

- On a 256 × 256 focus, `ndarray::simd::bf16_tile_gemm_16x16_packed` gives walk counts equal to a triple-loop oracle exactly, and `count > 0` equals Boolean composition (1 %, 10 %, 50 %, skewed hubs). 5 guards disable-verified.
- The tier that ran is the F32x16 FMA polyfill (no AMX, no `avx512_bf16` on this host): `A·A` about 19 ms. The bit arm: composition 2.6–25 µs, walk counts by popcount 165–192 µs, triangles 1.9–72 µs. Staging bits to BF16 (16 KiB to 256 KiB) costs 150–400 µs, more than the whole bit composition.
- The tier that ran is the F32x16 FMA polyfill (no AMX, no `avx512_bf16` on this host): `A·A` about 19 ms. The bit arm: composition 2.6–25 µs, walk counts by popcount 165–192 µs, triangles 1.9–72 µs. Staging bits to BF16 (16 KiB to 384 KiB) costs 150–400 µs, more than the whole bit composition.
- The polyfill allocates per output element (`ISS-BF16-POLYFILL-PER-ELEMENT-ALLOC`), so this host measures allocation, not GEMM.

## Open
Expand Down
2 changes: 1 addition & 1 deletion .claude/plans/d-rmap-2-context-tile-algebra-probe-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Report: total bound cost, sorted-index creation/maintenance, native scan time, r
| 1 % + 4 hubs | 2 706 | 20 273 | 2.6 µs | 165 µs | 5.8 µs | 150 µs | 19.7 / 19.4 ms |

- **§3's exactness claim holds as measured.** BF16 walk counts equal the oracle exactly (`assert_eq!`, not a tolerance), and `count > 0` equals Boolean composition, on all four maps.
- **On this host the bit arm wins every cell**, including walk counts. Popcount of `row_i(A) ∧ row_j(Aᵀ)` gives the same counts as the GEMM in about 170–190 µs, against about 19 ms. Staging alone (bits to dense BF16, 16 KiB to 256 KiB) costs more than the whole bit composition.
- **On this host the bit arm wins every cell**, including walk counts. Popcount of `row_i(A) ∧ row_j(Aᵀ)` gives the same counts as the GEMM in about 170–190 µs, against about 19 ms. Staging alone (bits to dense BF16, 16 KiB to 384 KiB: the BF16 matrix, packed B blocks and row-major B blocks, 128 KiB each) costs more than the whole bit composition.
- **The 19 ms is the polyfill's shape, not GEMM's.** `ndarray::simd_ops::bf16_tile_gemm_16x16` allocates two decode buffers per call, then one strided B-column buffer and one horizontal reduce per output element: about 257 heap allocations per 16 × 16 call, 65 000 per 256 × 256 product. The packed entry on this tier also unpacks and allocates per call. Recorded as `ISS-BF16-POLYFILL-PER-ELEMENT-ALLOC`; the row-major entry is no faster, so the unpack is not the cost.
- **Two conclusions, kept apart.** (1) *Measured:* on this host's F32x16 polyfill tier, the bit arm wins every cell, and BF16 is exact. (2) *Not measured:* nothing here says anything about BF16 or AMX tile hardware performance. The polyfill's cost is dominated by allocation, so it is not even a lower bound on what `TDPBF16PS` or `VDPBF16PS` would cost. No layout decision may cite (1) as evidence about (2).
- **Not measured:** AMX and `VDPBF16PS` hosts; dense relations above one focus (blocked 256 × 256 tiles); weighted or evidence-bearing relations, which §3 excludes anyway.
Expand Down
4 changes: 3 additions & 1 deletion crates/mork-pathmap-probe/src/tile_gemm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,16 @@ impl Bf16Staged {
}
}

/// Bytes held: the BF16 matrix and the packed blocks.
/// Bytes held: the BF16 matrix, the packed blocks and the row-major
/// blocks kept for the polyfill entry.
pub fn bytes(&self) -> usize {
self.a.len() * 2
+ self
.b_blocks
.iter()
.map(|b| b.data().len() * 2)
.sum::<usize>()
+ self.b_rows.iter().map(|b| b.len() * 2).sum::<usize>()
}

/// Walk counts through the row-major polyfill entry (no pack, no unpack).
Expand Down
9 changes: 9 additions & 0 deletions crates/mork-pathmap-probe/tests/tile_gemm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,12 @@ fn composition_respects_direction() {
assert!(!c.get(2, 0));
assert_eq!(c.edges(), 1);
}

/// The reported BF16 size counts every buffer the staged object keeps: the
/// 256 × 256 matrix, the packed B blocks and the row-major B blocks, each
/// 256 × 256 BF16 values.
#[test]
fn bf16_bytes_count_every_retained_buffer() {
let staged = Bf16Staged::stage(&BitMat::from_edges([(0, 1), (1, 2)]));
assert_eq!(staged.bytes(), 3 * 256 * 256 * 2);
}
Loading