Skip to content

fix: l2_stale accessors, tern I2FP fixed latency, fp8 v2 battery path rule - #247

Draft
aien-spark wants to merge 3 commits into
mainfrom
fix/l2-stale-tensor-layout
Draft

aien-spark wants to merge 3 commits into
mainfrom
fix/l2-stale-tensor-layout

Conversation

@aien-spark

@aien-spark aien-spark commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Three fixes for CUDApp-owned items that failed in the omega-mv #924 chip window (window-20261101T005524Z):

  1. l2_stale (3a184e4): tests/gpu_l2_stale_test.c copied a private struct layout. Its w.va sits at offset 16, but the real OmegaGpuFp8Tensor (src/omega_gpu_fp8_api.c:26-32) has allocation_epoch, owner_generation and s_mul, so w sits at offset 32. On the chip this showed up as mirror 0x2. The test now reaches the tensor through the accessors in src/omega_gpu_fp8_internal.h.
  2. tern (b09ac5b): bc16eab (Sass#4) put I2FP on a write scoreboard. On the chip, f32 q|k|v gave 2040 wrong rows out of 3840; the stall-6 fixed encoding gave 0. Now I2FP is fixed latency again, its readers sit at least OMEGA_TERN_I2FP_LAT (19) cycles behind with no scoreboard, and the f32 epilogue issues I2FP first. gpu_tern_sched_test now treats a scoreboarded I2FP as a violation.
  3. fp8_v2 test (03e8a89): the v2 chip battery expected a generated kernel for 8 shapes with k > 4096. omega_fp8_gemv2_spec_ok refuses those shapes (rows*ks*lane_bytes > 128), so general_gemv serves them. The battery now derives the expected path from the generator's shape rule and FAILs on a mismatch in either direction. A point served by a kernel must still hit the kernel cache, and a point on the general path must give bit-identical output on a second call down the same path.

Host results:

  • make test-gpu-tern-sched rc=0, PASS 45/45 f32 specs. The red control (tree before b09ac5b) fails 0/45.
  • make test-gpu-fp8 rc=0: 4997/0 host-only, 214/0 sim.
  • gpu_l2_stale_test builds with -Werror.

Chip: NOT_RUN on this branch.

omega-mv #924 pins c944ee8 (branch fix/924-pin-backport), which is 127387d plus these three commits cherry-picked. This branch is based on main, and main pins a different omega-bridge (ead98302, draft omega-bridge#36). That pin does not match the converter #924 is staged with.

Draft. No labels.

…t copy

gpu_l2_stale_test hand-copied struct OmegaGpuFp8Tensor as {experts,n,k; w; s}.
src/omega_gpu_fp8_api.c has since added allocation_epoch and owner_generation
ahead of w (and s_mul after s), so the copy read allocation_epoch as w.va and
every chip run stopped at 'FAIL mirror struct does not match omega (entry w_va
0x1004133000 vs mirror 0x2)' (omega-mv#924 window C, 2026-11-01) before any L2
measurement.

The test now uses the library-internal accessors that omega_gpu_fp8_slots.c
already uses (omega_gpu_fp8_internal.h): omega_gpu_fp8_tensor_entry for the
VAs, omega_gpu_fp8_tensor_cpu_view for the CPU weight mapping and
omega_gpu_fp8_tensor_sync_to_gpu after the host rewrite (session sync on w and
s; the sync is a barrier, s is unchanged). No layout copy remains.
… scoreboard

Sass#4 (bc16eab) emitted I2FP with a write scoreboard (K_VAR, stall 4)
and let its FMUL reader wait on that scoreboard. It was host-tested only.
Chip A/B on GB10 (omega-mv #924 window 20261101T005524Z, gpu_tern_test
chip f32 q|k|v segments, n=3840 k=2560): the scoreboard encoding gives
2040 of 3840 rows wrong; the pre-Sass#4 fixed encoding gives 0. The
scoreboard wait does not hold the reader.

- i2f() always emits K_FIXED (no scoreboard); I2FP is back in
  tern_fixed(); the scheduler makes its dst ready at T + OMEGA_TERN_I2FP_LAT.
- The f32 epilogue issues I2FP first, ahead of the segment-sum, IMAD
  and LDG work, so the FMUL reader is >= 19 cycles behind without
  extra stalls.
- omega_tern_i2fp_violations no longer accepts a scoreboard wait: only
  distance >= OMEGA_TERN_I2FP_LAT makes a reader safe.
- gpu_tern_sched_test: check 1 requires wb == 7 and the distance; the
  synthetic "I2FP on scoreboard 0, FMUL waits on it" is a violation.

Host: make test-gpu-tern-sched PASS (45/45 specs). Red: the same test
against the bc16eab codegen FAILs 2 checks (0/45 specs). Chip: NOT_RUN.
…nt 2's shape rule

Under --variant 2 the chip battery's q38 shapes (k 5120, 6144, 17408)
and the 256x32768 width cap are outside the variant-2 generator's rule
(a warp's whole row group in one register set: rows*k/32 <= 128 B, so
k > 4096 has no spec). Host-staged calls there are served by the general
fallback (info->general = 1), which caches no generated kernel, so
"second-call-identical" (which also required kernel_cache_hit) failed
on 8 points with rc=OK bad=0 (omega-mv #924 window 20261101T005524Z).

The expected path is now decided from the generator's own spec rule
(v2_can_build), not from the API: a point must be served by the kernel
unless variant 2 cannot build it, and a mismatch in either direction
FAILs. The second call must take the same path and be bit-identical;
the kernel cache hit is still required whenever a kernel served it.
kernel_cache_hit is not faked for the fallback. Timing reps run only on
the kernel path; the chip line and JSON record path/general.

Host: make test-gpu-fp8 PASS (4997 + 214 checks). The classification
of all 22 battery shapes matches the chip run: the 8 failing points are
exactly the 8 v2_can_build == 0 shapes. Chip: NOT_RUN.
@aien-spark aien-spark changed the title tests: gpu_l2_stale reaches the tensor through accessors, not a struct copy fix: l2_stale accessors, tern I2FP fixed latency, fp8 v2 battery path rule Nov 1, 2026
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