Skip to content

train 1114060327: #3005 #2985 (CI only) - #3303

Closed
ashhart wants to merge 24 commits into
mainfrom
lead/train-1114060327
Closed

ashhart wants to merge 24 commits into
mainfrom
lead/train-1114060327

Conversation

@ashhart

@ashhart ashhart commented Nov 14, 2026

Copy link
Copy Markdown
Owner

CI for a landing train: #3005 #2985 stacked on main in that order. Nothing merges from this PR: each PR above lands on its own once this tip is green, and this PR is then closed.

laudney and others added 24 commits November 14, 2026 05:53
A serve config file needs a reader, and Zig's standard library has
none for TOML. This one takes a strict subset of TOML 1.0, top-level
key = value lines with strings, decimal numbers, booleans and arrays
of them, and refuses the rest by line, so every file it accepts is
valid TOML with the same meaning and tables stay free for later use.
A launch of ten to twenty flags could live only in a shell script,
where vLLM and SGLang take a config file. serve --config FILE.toml
now turns the file's keys into flags ahead of the command line's,
so the one parser runs and the command line wins; each key is
checked against the flag table first, so an unknown key, a wrong
type or an unserved flag is refused with the file and its line.
Operators need the key rule, the precedence and its three
consequences before they move a launch into a file. This adds the
flag's row to the README table, a page with an example, the value
types, what the reader refuses and how errors name the file, and
the changelog line that also records the --compact-at fix.
The engine now lists --config in its capabilities, so the launcher
took it as an extra flag while it checks only the tokens it sees,
and a file could turn on --cortheon, a learning flag or a key that
Settings manages. The flag joins the managed set, with tests for
both spellings, and the config page states that an integer loses
its leading plus and that the launcher refuses the flag.
The maintainer accepted serve --config with four conditions, since
the file chooses what is served and can hold a key. A relative path
now starts at the file's folder, a file that other users can write
is refused before it is read, a pair of switches has one key
(thinking = false), and arrays hold strings only; the flag table
marks which flags name a path.
The maintainer's review of serve --config found that a refused
value named no line, that a command-line key left the file's key in
force, and that the file was checked by path and then read by path.
Each value now runs its flag's own check before the merge, a
repeatable flag on the command line replaces the file's list, the
file is opened once without following a link and read through that
handle, an api-key file must be unreadable by others, and a path
flag refuses a tilde.
…a_forward.zig has room for TF_GLM_DSEL

A move only: row_step, max_pieces, ranges and Pieces keep their text in
cuda_forward_pieces.zig, beside the pieced exchanges that use them, and
cuda_forward.zig re-exports them, so fw.Pieces, fw.ranges and the rest keep
working. cuda_forward.zig was at the 600-line limit; it is 545 now.
…GLM_DSEL)

MiaAI-Lab's patch 0067 (glm-dsa-decode-select-many-ctas, in
MiaAI-Lab/GLM-5.3-Flash-DGX-Sparks-1104 0049d7c, Apache-2.0), moved onto
main 8be9c40. For decode windows (rows <= Scratch.bits_rows, np >= 4096)
tf_glm_select_rows_wide (one 1,024-thread CTA a row) gives way to two
launches in glm_index_decode.cuh: tf_glm_dsel_scan marks each span's pools
above and at a sampled floor on many CTAs, and tf_glm_dsel_merge picks a
row's K pools from those words (the ties at the floor, the candidates
through tf_glm_select_rows' radix select, or the full-row select). Every
path returns tf_glm_select_rows' bytes. TF_GLM_DSEL=0 keeps today's select
(unset or 1: on; anything else is refused). Decode buffers' Scratch.ls
grows to hold the bit words (about 0.8 MiB a set at 864K); prefill buffers
keep bits_rows 0.

The patch was cut on Mia's stack: the context naming absorb_mma and
glm_glue_p2p/num (not on main) is left out, the rest is as written.
Checks: test-glm-index-host (the switch and the scan's grid) and
test-glm-index-emulate (the kernels as host C++, all four paths, against a
plain top-K); glm-index-check (GPU) compares the device paths.
…e select's comments are one line each

TF_GLM_DSEL is a glm row of platform/environment.zig (a flag: 0 or 1, default
on), in docs/environment.md and in cuda_env_test.zig's switches, so a malformed
value is refused by name with the other GLM settings when the model opens, and
cuda_sparse.zig's own parser goes. The decode select's comments in
glm_index_decode.cuh, cuda_sparse.zig, cuda_glue.zig and glm_index_check.zig are
one line each within 120 columns; the merge's paths are named at its branches.
lean_check.py finds nothing new against main.
… nvcc 13.0's and 13.3's records

contract_glm_dsel.zig registers tf_glm_dsel_scan and tf_glm_dsel_merge as a replacement of tf_glm_select_rows on
the wide select's scores, host rule and checks: each row's K pools come out of cuda_sparse.decodeSelect, their bytes
must equal the 128-thread kernel's on the same scores, then every row's picks the host's rule. It runs at the wide
select's three shapes, where cuda_sparse launches the decode select instead, and at a 1M window's bucket (8 rows of
260,096 pools), in the Index group beside the index scores and the wide select. Its planted control, the same
launches told past two spans that the bucket is one span (4,096 pools) short, goes red at the shapes gate. Gate 5's
records come from kernel-contract-limits over sm_80 to sm_121 fatbins of nvcc 13.0.88 and 13.3.73; 13.3 differs for
the scan on sm_120 and sm_121 (45 registers, 48 on 13.0). nvcc 13.2 was not at hand. The docs name both launches
and the scan in 13.3's set.
…st test, the CHANGELOG line, and one-line comments above

cuda_state.zig's selectLs gives a Buffers' selectTokens list bytes (`ls`) and
the rows of decode select bit words they hold (`bits_rows`), and make() takes
both from it. A host test checks, at a 4K and a 1M window, that a decode's ls
holds bitsBytes(bits_rows, np_max) with bits_rows min(seg, wide_rows), and that
a prompt's buffers keep bits_rows 0. The comments commit 3 had put at the ends
of long lines (cuda_glue.zig's Set, cuda_sparse.zig's decodeSelect path
argument, Scratch, dsel_target and dselScanCtas' 0, and glm_index_check.zig's
planted scores) are one-line comments above. CHANGELOG.md has an Unreleased
line for #2722 with the credit.
stage.zig stages device memory through tcp.zig behind the same Collective VTable (Kind.tcp). A call only queues on its
stream: the stream writes the call's ready word, then waits for its done word, 64-bit words in pinned host memory. A
proxy thread sees ready, copies the input into a pinned slab on a stream of its own, moves it with tcp.zig, copies the
result back and sets done. The caller's stream gets no copies of ours: with copies queued on it around the wait, two
ranks of one process hung or read stale bytes on ROCm 10.0. A call larger than Options.part_bytes (default 4 MiB,
checked alike when the ranks open) moves in parts, and the frame header's spare word now names the part, so one call in
two parts never pairs with two whole calls.
A failure sets every done word, so no stream waits on it, and shows at the next call or at check. A capturing stream is
refused, and allGatherV moves whole strides.

stage_hip.zig is the HIP device: hipStreamWriteValue64 and hipStreamWaitValue64 on mapped coherent host memory, refused
by name on a GPU without them, and the proxy's copies on a non-blocking stream of its own. stage_test.zig runs
host_test's contract bodies over a device whose copies are memcpy, whole and in 64-byte parts, plus part, size, capture
and device-failure refusals; stage_later_test.zig uses streams that run later, so calls return before anything moves
and an abort still lets a held stream drain; stage_hip_test.zig checks the same on a GPU, two ranks of one device over
loopback, and skips without HIP. `tf-tp-test tcp-hip` runs tcp-host's checks and timings from HIP memory. Nothing
selects it yet, and no other backend changes.
Keep headless per-stream verification at one row while opting into exact cross-stream rounds. Retain the pipelined lone path and test shared transitions without drafts or copies.
@ashhart

ashhart commented Nov 14, 2026

Copy link
Copy Markdown
Owner Author

CI red on this tip (zig,python); the PRs go on as two smaller trains.

@ashhart ashhart closed this Nov 14, 2026
@ashhart
ashhart deleted the lead/train-1114060327 branch November 14, 2026 07:15
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.

5 participants