Repository navigation
Conversation
A lone stream's prompt pass ran the GDN block as three launches: fn_gdn_front wrote every row's q, k, v, g and beta as fp32 (41 KB a row, 63 MB for a 1536-row chunk), fn_gdn_chain_tpr read them back for the delta rule, and fn_gdn_norm read the fp32 readouts again for the gated norm. On a GB10 the front is DRAM-bound (~240 GB/s), so running it beside the chain on a second stream hides almost nothing. fn_gdn_fused keeps those rows in shared memory: 256 threads walk the chain (fn_gdn_chain_tpr's code) while 128 producer threads make the next 16 rows' inputs with fn_gdn_front's op sequence and the gated norm of the previous 16 with fn_gdn_norm's. Each row's arithmetic is unchanged, so the bits are too. The recurrence is row by row, so no cut of the rows changes them either. Passes of 64 rows or more with one stream use it; TF_FLASHNEXT_GDN_FUSED=0 keeps the three launches. - Kernel contract: nonfinite, repeat and 6 shapes bit-equal to front -> rows_to -> norm; gate-5 record (sm_80/86/89/120/121). - GDN block alone, GB10: 1.907 -> 1.547 ms at 1536 rows, 5.008 -> 4.078 ms at 4096 (-19 %); bytes equal from 64 to 4096 rows. - Served FP4-Local, MTP and prompt cache on: 136 of 136 token hashes equal to main's (greedy and seeded, c=1 and c=4, cold, warm and resumed); cold TTFT at ~10k 7.81/7.85 -> 7.72/7.67 s, at ~38k 30.98/30.24 -> 30.02/29.93 s.
ashhart
added a commit
that referenced
this pull request
Oct 23, 2026
…rows and the state alias The registered contract covered 64 and 300 rows, so the shapes gate never ran the default chunk (1,536) nor the most a chunk may ask for (16,384). The served shapes now carry the production chunk constants, and the gate derives the tile seams from them. Production binds the fused block's state as both its input and its output, but the contract allocated the two apart and declared no alias. The spec now declares the in-place state, the launch passes one buffer for it, and every launch restores the starting state, so the repeats compare the same pass. The new host test in contract_flashnext_glue_test.zig covers the served range and the alias.
ashhart
added a commit
that referenced
this pull request
Oct 23, 2026
…er index, and the Linux build compiles the glue The M45 fix-up changed Glue.out to return the buffer index (!u64), but the chain, scores, fused and read-out cases still called it as a statement, so Zig 0.17 rejected the discarded value: zig/tests/cuda/contract_flashnext_glue.zig:166:17: error: value of type 'u64' ignored. The callers discard the index where nothing needs it, and the fused case keeps it, where the state is bound in place as its own output. The gate that would have caught it: the runner now compiles the contract glue's device path (main.zig's compileContractGlue), so the Linux build of the CUDA test binary sees the same body the device runs. Without the fix, `zig build compile-cuda-tests -Dtarget=aarch64-linux-gnu` fails on that error; with it, the step succeeds (10/10 steps, the tf-cuda-test executable for aarch64-linux-gnu). The host contract test still passes (2/2). Nothing of the contributor's is amended.
Owner
|
Thanks @jschmied, this is on What we checked on a DGX Spark (GB10):
Closing as landed. It ships in the next release. - Synthema, Ash's AI Assistant. |
ashhart
added a commit
that referenced
this pull request
Oct 24, 2026
#1155's first record and main's #1217 both change gdnBlock in zig/src/families/flashnext/cuda_batch.zig: the record keeps each lane's rows on its own conv window and state, and #1217 runs a lone pass's prompt DeltaNet in one kernel. The record carries the shared pass; this commit carries #1217's block onto it. zig/src/families/flashnext/cuda_batch.zig:272-276: a lone pass keeps its projection and conv window before the fused branch, so the one-block path fills the rollback's keep as main does. zig/src/families/flashnext/cuda_batch.zig:278-283: the fused launch for a lone pass of 64 rows or more. zig/src/families/flashnext/cuda_batch.zig:305: the gated norm through gdn_fused.norm, the same kernel and grid as the inline launch it replaces. Refs #1155
9 tasks done
ashhart
added a commit
that referenced
this pull request
Oct 24, 2026
…e ranked scoring Carried onto main: the CUDA build wiring keeps main's own registrations beside the new one. Main holds the architecture contract test inline (zig/build/cuda.zig:285) and #1217's glue host beside it (:286); the scoring host takes the proposal host's place (:287) because zig/build/flashnext_scoring_host.zig:4 calls the proposal host's own steps, so the proposal checks and the score step both run. The file keeps its 600 lines. The worker's exit still closes the scoring queue (zig/src/core/lane_host.zig:522 and zig/src/core/lane_host_score.zig:66), and the ranked vtable still advertises the score hook for one rank only (zig/src/families/flashnext/cuda_lanes.zig:214, :217 and :218).
Owner
|
This shipped in TensorFold 1.1.4: https://github.com/ashhart/TensorFold/releases/tag/v1.1.4 Thank you @jschmied for the contribution. - Synthema, Ash's AI Assistant. |
ashhart
added a commit
that referenced
this pull request
Oct 25, 2026
Carried onto main: zig/src/core/contract/flashnext_tile_records.zig:13 retains #1217's fn_gdn_fused record (384 threads and 82496 shared bytes), while :14 keeps #1169's measured qsa_tile register counts of 218 on sm_120 and sm_121. The paging entry-point records in flashnext_pages_pending.zig stay as authored. Both registrations describe kernels present on this line; neither record replaces the other.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A lone stream's prompt pass runs the GDN block as three launches:
fn_gdn_frontwrites every row's q, k, v, g and beta as fp32 (41 KB a row, 63 MB for a 1,536-row chunk),fn_gdn_chain_tprreads them back for the delta rule, andfn_gdn_normreads the fp32 readouts again for the gated norm. On a GB10 the front is bound by DRAM (~240 GB/s), so overlapping it with the chain on a second stream hides almost nothing (measured: -0.5 % at 1,536 rows).fn_gdn_fusedkeeps those rows in shared memory:fn_gdn_chain_tpr's code;fn_gdn_front's op sequence;fn_gdn_norm's.Every row's arithmetic is unchanged, so the bits are too. The recurrence is row by row, so where the rows are cut (chunk size, resume point) does not change them either. Passes of 64 rows or more on one stream use it;
TF_FLASHNEXT_GDN_FUSED=0keeps the three launches.Bytes (state, readouts, gated rows, sums) are equal from 64 to 4,096 rows.
Checks
zig build test -Dnvcc=/usr/local/cuda/bin/nvcc: exit 0 (278/278 steps; 3,491 of 3,506 tests passed, 15 skipped). lean_check: 0 new against the merge base.zig fmtis clean.Served Flash Next FP4-Local (MTP and prompt cache on, chunk 1,536)
Token hashes: 136 of 136 equal to main's. This covers greedy and seeded, c=1 and c=4, and cold, warm and resumed requests.
That is about -1.5 to -2 %.
Gotchas
fn-gdn-fused@c184e94c(two commits), based onmain@da275a360; it test-merges cleanly onto today'smain(1705bf542).cuda_batch.zigandcuda_batch_state.zig, which [Draft] EXL3 Flash Next on CUDA: TP=2, BF16 paging, cache reuse, graphs #1113, Flash Next CUDA: drafted windows of several streams verified in one pass #1069 and Living Weights on Qwen3.8 Flash Next (CUDA, GB10): the pocket in every pass, the trainer, and --slide #896 also change, andcontract_tests.zig, as MiniMax H3 / FastH3 on CUDA in the checkpoint's bf16, one GPU or several Sparks over RoCE #958, music3: MiniMax Music 3 lyrics to song on one CUDA GPU, from Zig (new family; proposal) #982, music3: MiniMax Music 3 lyrics to song on Metal, from Zig (stacked on #982) #987 and radio CUDA: fuse the tower's bias, activation and residual launches #1141 do. These are textual conflicts only (the fused path is one branch in the GDN block's launch).qwen3_5CUDA) is unchanged: there, every fused form I tried was exact but slower (its prepare step is compute-heavy and four producer warps can't keep up).