Skip to content

SuperSLM 1.13.0

Choose a tag to compare

@dansupergameprogrammer dansupergameprogrammer released this 16 Oct 00:01
· 49 commits to main since this release

SuperSLM 1.13.0

Released 2026-10-15.

SuperSLM 1.13.0 brings 1.12.0's paged K/V memory to the GPU backend. A GPU page pool holds the K/V of
budgeted sequences and prefixes in pages. A budgeted sequence reserves only the pages its budget
needs, sequences that adopt a frozen prompt prefix map the prefix's full pages instead of copying
them, and a budgeted sequence's save, the new SLM6 blob, holds its live rows, so its size follows
its live length. It also folds in the fixes planned for a 1.12.1: a no-budget CPU save now writes a
large block with streaming stores, aimed at 1.12.0's save slowdown (the bytes are unchanged; on the
release machine a full-length save reads 1.27 and 1.14 times 1.11.0's time where 1.12.0's read 1.88
to 1.93 times, so it is still slower than 1.11.0's, see Speed), and two GPU defects that shipped in
earlier releases are fixed (see Fixes).

GPU sequences made by sslm_gpu_seq_create keep their own whole-cap buffer and keep saving SLM5,
which 1.12.0 still reads. They now address K/V through a page table with one page, which by
construction is the old flat layout. Their outputs are meant to be byte-identical to 1.12.0's; the
release machine's check compares them with a record taken on this branch's build before the
page-table change, not with a 1.12.0 build (see Verification). On the NVIDIA GeForce RTX 2080
SUPER, superslm_tests with its GPU cells, the GPU prefill-read suite and the GPU allocation-status
suite passed on this branch before its last library fixes, and the two race cells, the GPU
batched-prefill suite and the GPU red-suite cells listed under Verification passed after them with
the D3D12 debug layer on, while the
cross-vendor battery reads red for reasons that predate this release and some release-machine runs
are still open; nothing in this release is verified on the AMD Radeon RX 7900 XTX (see
Verification). Paged GPU decode reads within its bar of 5% slower than the one-page view, not
faster (see Speed). The memory savings come only from the new pooled verbs. Two GPU
behaviours change for every host (see Compatibility): two decode calls raced on one sequence
handle from two threads (sslm_decode_step_gpu, a batch slot, the bridge decode or the finish, in
any pairing) leave one running and return SSLM_BUSY to the other where it was undefined, and a
call that would reset the process's GPU command list while earlier work is still unobserved
returns SSLM_BUSY where it was undefined. The shipped shaders changed, so deploy the whole 1.13.0 shader
set. The CPU C ABI is unchanged (51 verbs, no new status), and no model artifact needs reconversion.

What changed

  • GPU page pools. sslm_gpu_kv_pool_create(ctx, model, page_count, &pool) creates one device
    buffer of page_count pages, zero-filled before it returns, with a host mirror of the same size.
    A GPU page is B positions, where B is the artifact's kv_block_size when it divides the
    context cap and the cap otherwise: 16 for converted artifacts at cap 4,096. That is not the CPU's
    page (64 positions at Qwen2.5-0.5B, cap 4,096), so the two backends' page counts differ for the
    same cohort. A page of Qwen2.5-0.5B is 96 KiB (24 layers × K and V × 2 K/V heads × 16 positions ×
    64 bytes) and of Qwen2.5-1.5B 224 KiB, from the page rule. sslm_gpu_kv_pool_destroy destroys an
    empty pool and refuses with SSLM_MODEL_HAS_LIVE_SEQUENCES while anything drawn from it lives.
    sslm_gpu_kv_pool_stats reports the pool's page count, free and shared pages and its B.
  • Budgeted GPU sequences. sslm_gpu_seq_create_budgeted(ctx, model, pool, budget, &seq) takes a
    budget, 1 ≤ budget ≤ cap, and reserves R(budget) = min(ceil(budget / B) + 1, ceil(cap / B))
    pages at create, the CPU's rule, or returns SSLM_GPU_KV_POOL_EXHAUSTED with nothing drawn. A
    pooled sequence's cap is the model's context cap; unlike sslm_gpu_seq_create's context_cap,
    the host does not choose it. Decode and prefill then take pages only from that reservation. At the
    limit, min(origin + budget, cap), below the cap, a decode returns SSLM_GPU_KV_BUDGET_EXCEEDED
    with no row written, and a prefill that reaches the limit commits the tokens below it and then
    returns SSLM_GPU_KV_BUDGET_EXCEEDED, with the ready flag set when any landed, so the next bridge
    decode finishes the last committed token (the prefill bridges' header comments state it); at the
    cap the existing cap behaviour applies. Every other GPU verb (decode, the batch,
    prefill, the finish, reset, release, schema binding) takes a pooled sequence as it takes a
    dedicated one, and its reset and release touch only its own pages.
  • Shared GPU prefixes. sslm_gpu_prefix_begin, sslm_gpu_prefix_set_schema,
    sslm_gpu_prefix_prefill, sslm_gpu_prefix_freeze and sslm_gpu_prefix_release build budgeted
    prefixes in a pool, base-only. sslm_gpu_prefix_begin_from builds a prefix on a frozen parent,
    sharing its full pages and copying its partial last page, so prefixes nest (a world, then a persona
    on the world). sslm_gpu_seq_adopt_prefix adopts a frozen prefix onto a pooled sequence the same
    way, with the CPU adopt's field and schema rules; every check runs before any state change. One
    failure comes after them: if uploading the prefix's partial last page fails, the adopt returns
    the fault's status and leaves the sequence reset, its earlier history gone. A shared page is
    freed when the prefix and every holder that maps it have let go of it.
  • Save and restore, SLM6. A pooled sequence's sslm_gpu_seq_save writes SLM6: the SLM5
    header and tail, then its mode, budget and origin, its residual, and its rows from position 0 to
    its live length (an adopted prefix's span included), so its size follows its live length.
    sslm_gpu_seq_restore_into_pool restores an SLM6 blob into a fresh pooled sequence with its
    budget and origin, and takes an optional live prefix handle: when the handle matches, the restored
    sequence maps the prefix's pages again, and otherwise it restores privately and still succeeds.
    Dedicated sequences keep writing SLM5, and sslm_gpu_seq_restore keeps reading SLM5 and SLM4.
    Each restore verb refuses the other's blobs with SSLM_GPU_HOLDER_MODE_MISMATCH, changing
    nothing. In the software-GPU runs, a GPU SLM6 blob's K/V section equals the CPU SSB6 blob's of
    the same state byte for byte; the two remain separate formats, and neither backend restores the
    other's blobs.
  • Statuses. Six SslmGpuStatus values are appended, ordinals 24 to 29:
    SSLM_GPU_KV_BUDGET_EXCEEDED, SSLM_GPU_KV_POOL_EXHAUSTED, SSLM_GPU_KV_POOL_TOO_LARGE (a pool
    above 2^32 bytes, the reach of the shaders' 32-bit offsets: 43,690 pages at Qwen2.5-0.5B and 18,724
    at Qwen2.5-1.5B, from the page rule), SSLM_GPU_HOLDER_MODE_MISMATCH, SSLM_GPU_PREFIX_REJECTED
    and SSLM_GPU_PREFIX_SCHEMA_MISMATCH. No existing ordinal moves.
  • Work in flight, stated. gpu_1p0.h now states two promises. Safety: the library never resets
    a device's command allocator while work submitted on it has not been observed complete, whatever
    path reached the reset. A clean status: a guarded verb that would do so returns SSLM_BUSY and
    changes nothing, or SSLM_DEVICE_LOST once a submission is stranded, never a Busy a retrying host
    would spin on. The header lists, for every verb, which device it resets, submits or waits on, and
    the order of each verb's refusals. Both hold for a host that serializes every call that submits on
    a device, as before; the list of those calls is now complete (see Compatibility).

gpu_1p0.h adds 12 verbs and 2 handle types (SslmGpuKvPoolHandle, SslmGpuPrefixHandle), plus
two test-only verbs (sslm_gpu_test_only_peek_pool_mirror_bytes,
sslm_gpu_test_only_wait_in_flight) that a host does not call. docs/api.md (Paged KV memory on
the GPU
) is the summary, and the header is the contract.

Fixes

  • A barrier race in the shipped shaders. Four steps run more than once in one dispatch: the
    residual candidate of the attention and MLP residual sites, the bias reconcile and the funnel
    maximum. Thread 0 reset a shared flag or maximum slot for the second run without a barrier after
    the first run's reads, so another thread could read the reset value and reach a barrier the others
    did not. The fix adds the barrier. It was found by running the GPU path on a software Vulkan device
    (lavapipe), where the race fired on every run: 16 GPU-against-CPU mismatches in superslm_tests
    went away with it. In earlier releases' certification runs on the two certified GPUs, GPU outputs
    were byte-identical to the CPU's, so the race had not shown there. No output is meant to change.
    On the RTX 2080 SUPER, superslm_tests with its GPU cells passes with the fix (see
    Verification); the AMD card has not run it.
  • No-budget CPU save speed. 1.12.0's no-budget sslm_seq_save copied the block one page run at
    a time, each copy too small for the C runtime to use non-temporal stores, so every destination
    line was first read into the cache, and the save took 1.14 to 2.00 times as long as 1.11.0's. A
    block of 16 MiB or more (24 MiB at Qwen2.5-0.5B, cap 4,096; 448 MiB at Qwen2.5-1.5B, cap 32,768)
    is now written with streaming stores on x64; a smaller block, and every non-x64 target, keeps
    1.12.0's copy. The bytes are unchanged: blobs equal 1.11.0's and 1.12.0's at 9 lengths, and the
    streaming path is checked against the pinned 1.11.0 blobs at every destination offset from 0 to
    63 (cell 9.3s). On the release machine the save is faster than 1.12.0's but a full-length save
    still reads slower than 1.11.0's (see Speed).
  • Two decodes racing on one GPU sequence. Two threads decoding the same sequence handle at once
    is not a supported use, but in 1.12.0 and earlier it was undefined: both calls could pass the
    handle's checks and record on the one command list together, which corrupted the heap under the
    D3D12 debug layer and, without it, returned SSLM_OK to one call and SSLM_DEVICE_LOST to the
    other and left the sequence unreleasable. Now each of the four decode entry points,
    sslm_decode_step_gpu, a slot of sslm_decode_step_batch_gpu, SslmGpuSeqDecodeStepForG5Bridge
    and SslmGpuSeqFinishTokenForG5Bridge, takes a per-handle claim before it reads the handle and
    holds it until it returns. Of two such calls raced on one handle, in any pairing, one runs and
    the other returns SSLM_BUSY having changed nothing (a batch slot reads SSLM_BUSY). Other
    verbs raced on one handle (embed, the prefill bridges, reset, save, schema binding, release)
    remain the caller's to serialize. Every pairing, on a dedicated and a pooled handle, is checked by
    the race cell, on the software GPU and on the release machine with the D3D12 debug layer on, and
    the t2112 cell's two sslm_decode_step_gpu calls read 289 of 289 there (see Verification).
  • Live-handle counts under two threads. A context's and a model's counts of live handles were
    plain integers, changed by calls the header lets run at once on different handles: two releases
    in 1.12.0 already, and from 1.13.0 also a budgeted create beside another create, and two pooled
    releases. A lost update could let sslm_gpu_model_unmap free a model a sequence still used, or
    make sslm_gpu_context_destroy refuse for ever. The counts are now atomic. A software-GPU cell
    that churns budgeted creates and releases on two threads beside a live dedicated sequence lost an
    increment before the fix and holds after it.

Found and fixed during development, never released: a host allocation failure while publishing a
GPU call's timing was swallowed into SSLM_OK by two publishes the pool work added; it now returns
SSLM_GPU_ALLOCATION_FAILED, as every other host allocation failure does. A pooled sequence's page
table was left in a shader-read state between uploads, so later uploads copied into it from a
state other than the one they declared; it now returns to the common state between uploads.
A refused sslm_gpu_prefix_freeze (the reserve's return failing) still marked the prefix frozen;
it now marks it only once the reserve is back. Releasing a prefix after its sequence's release
returned an error left a dangling handle; it now
completes unless the release returned SSLM_BUSY. The other changes since 1.12.0 are to comments,
test cells, test tools and build scripts, the coverage job's build list among them.

Memory, graded by admission

The figures are graded by what a pool admits, never by the library's page counts, on the 1.12.0
example cohort, an assumption, not a measured workload: a 1,000-token world prefix, 10 persona
prefixes of 200 tokens built on it with sslm_gpu_prefix_begin_from, the world handle released, and
50 budgeted sequences of 512 tokens each (5 per persona), each run to its budget. At Qwen2.5-0.5B
with cap 4,096 a GPU page is 96 KiB (16 positions).

  • A pool of 1,842 pages (172.7 MiB) admits the whole cohort, and a pool of 1,841 pages refuses
    exactly one create, the 50th, with SSLM_GPU_KV_POOL_EXHAUSTED (cell 10.5). For comparison, by
    arithmetic only: fifty dedicated sequences at cap 4,096 hold 24 MiB of K/V each, 1,200 MiB in all
    (the dedicated buffer's size, which the cell reads from a dedicated sequence's own save). A host
    need not size them so: sslm_gpu_seq_create takes the cap, and fifty dedicated sequences sized to
    what each cohort member needs (1,200 + 512 = 1,712 positions, 6,144 bytes each) hold 501.6 MiB,
    about 2.9 times the pool rather than about 7 times. The GPU has no block pool to refuse an eighth
    sequence, so there is no admission contrast.
  • After every sequence is saved mid-budget and at its limit, the world and personas rebuilt in a
    fresh pool and the world released, the 50 sequences restored with their persona handles fit
    in 1,842 pages, and 1,841 refuses exactly the 50th, for both saves (cell 10.7).
  • Restored without handles, the same blobs need 5,592 pages (5,591 refuses the 50th); after
    each sequence resets and re-adopts its persona the pool admits 113 more budget-512 sequences
    (cell 10.7).
  • Every sequence's tokens equal the CPU twin's, which equal a no-sharing 1.11.0 run (cell 10.3).

All four are confirmed on the real Qwen2.5-0.5B artifact on the RTX 2080 SUPER with the D3D12 debug
layer on, at commit 845918e, and again at 05e09d8, whose library code is the release's (see
Verification): 10.3 280 checks, 10.5 217, 10.7 793, 0 failures. They are not run on the AMD card. Each cell also has a
fixture leg, on the small synthetic model of the paged-KV suites, which passed on the software GPU
(10.3: 280 checks, 10.5: 217, 10.7: 793; 0 failures) and again on the release machine with the debug
layer on, after the last library fixes. The figures hold for this artifact's page size
only. Another model or cap has another page size and its own figures.

Speed

Every reading below is from one machine, the release machine's NVIDIA GeForce RTX 2080 SUPER
(adapter 0, Windows x64, debug layer off), on one driver, at the widths and lengths named, and is
not a statement about any other card, driver or width.

  • Paged GPU decode against the legacy one-page view. The claim is a bar: single-sequence GPU
    decode through a pooled sequence's page table is no more than 5% slower than a dedicated cap-size
    sequence through the one-page view of the same build. It passes on both rows measured, and it is
    not a speed-up: the 0.5B row reads about 1% faster and the 1.5B row about 3.7% slower.

    Row Paged arm Process medians of s Largest Spread (SD) Rate Verdict
    Qwen2.5-0.5B, cap 4,096, width 1,712 cohort member, adopted prefix −1.14, −1.11, −1.17, −0.94, −1.33% −0.94% 0.14 points about 31 tok/s PASS
    Qwen2.5-1.5B, cap 32,768, width 16,384 private restore, no prefix +3.78, +3.59, +3.74, +3.73, +3.68% +3.78% 0.08 points about 6.2 tok/s PASS

    Per pair, s is the paged arm's time over the legacy arm's, minus 1. A row is five processes on one
    boot; each loads the model, builds or restores both arms, decodes 4 untimed warm-up tokens per arm
    and then times 104 pairs, each token timed alone through the one-call decode
    (SslmGpuSeqDecodeStepForG5Bridge, which waits for the token), the order within each pair drawn
    at random, and both arms' tokens must be equal at every step. A row passes when the largest of its
    five process medians is at most 5%. The 0.5B row's paged arm is the first sequence of persona 0 in
    the cohort above, in a pool of exactly the cohort's pages, against a dedicated sequence at cap
    4,096 prefilled with the same 1,200 tokens; its pairs run at the cohort's last widths, 1,608 to
    1,711, so the last step attends to 1,712 positions. The 1.5B row's arms are restored from blobs
    saved at 16,380 tokens: the paged arm into a pool of its own reservation with no prefix (budget
    16,488), the legacy arm as a dedicated sequence at the cap; its pairs run at widths 16,384 to
    16,487. Before its readings counted, the harness was commissioned: a paged arm slowed on purpose
    by 17.65% of each call was rejected, and the same slowdown on the legacy arm was accepted.

    The legacy arm is the one-page view of 1.13.0, not 1.12.0's dedicated path; no measurement ties
    1.13.0's GPU decode speed to 1.12.0's, for dedicated or pooled sequences. Not measured: the AMD
    Radeon RX 7900 XTX, decode under the debug layer, batched decode, other widths or caps, a 0.5B
    pooled sequence without an adopted prefix, a 1.5B one with one, a prefix ending in a partial page,
    and other pool occupancies. The rows ran at 03a2088 (since then the library has changed only
    in the CPU save's zero fill), on NVIDIA driver 32.0.15.6094; the run's identity record does not carry the driver, so
    it was read from Windows on the same boot. The harness was commissioned on 2026-10-14, and its
    commissioning record and the run's receipt are filed with the release's records. The AMD leg of
    the decode timing is not run; it belongs to its own machine and this release states none.

  • No-budget CPU save against 1.11.0. The lifecycle save cell, at e30db83 (the library code of
    the branch head) built with MSVC 14.44, read against the release machine's 1.11.0 lifecycle record
    through a commissioned instrument; the cell's 66 checks are green. 1.13.0's save time against 1.11.0's:

    Model, cap Live length 16 1,000 The cap
    Qwen2.5-0.5B, 4,096 −19.7% −18.7% +27.0%
    Qwen2.5-1.5B, 32,768 −21.1% −20.4% +13.8%

    These are readings, not resolved changes: the comparison resolves a change only at 4 times or
    more, and every save reading is NO RESULT under that rule. Against 1.12.0, whose full-length saves
    read 1.88 to 1.93 times 1.11.0's, the full-length save is faster; it is still slower than 1.11.0's,
    by 27% at Qwen2.5-0.5B and 14% at Qwen2.5-1.5B. 1.12.0 was not re-read in the same run, so the
    comparison with it is across runs. In development, a benchmark of the copy pattern alone on a
    cloud Linux machine (not the release machine, and not the library's save call) read 1.70 times
    1.11.0's time for 1.12.0's copy and 1.08 times for the streaming copy, at Qwen2.5-1.5B's full-cap
    block; the release machine's full-length reading is the one that stands.

  • CPU lifecycle verbs. The same run read restore, release, reset and adopt at the short lengths
    taking 89% to 99.96% less time than 1.11.0's, changes the 4-times rule resolves. The CPU
    decode claims of 1.12.0 are unchanged and were not re-measured (the CPU decode paths did not
    change).

Compatibility and required action

These apply to every host, including one that calls no new verb:

  • Deploy the whole 1.13.0 shader set with the 1.13.0 library. Every K/V-addressing shader reads
    the page table, and the barrier fix touches the residual sites; the shaders and the library must
    come from the same release.
  • Two decode calls raced on one sequence handle (sslm_decode_step_gpu, a batch slot,
    SslmGpuSeqDecodeStepForG5Bridge or SslmGpuSeqFinishTokenForG5Bridge, in any pairing): one runs
    and the other returns SSLM_BUSY, changing nothing. It was undefined.
  • A second singleton-reaching call while earlier work is unobserved (for example, a decode of
    sequence A, then a decode of sequence B before sslm_gpu_ready has reported A complete) returns
    SSLM_BUSY, changing nothing. It was undefined: it reset the command allocator the earlier work
    was recorded on. Finish each submission (sslm_gpu_ready) before the next, or decode several
    sequences in one sslm_decode_step_batch_gpu call.
  • A stranded submission (one whose completion cannot be confirmed) makes every later guarded verb
    that reaches the process's submission device return SSLM_DEVICE_LOST, until the process
    restarts. 1.12.0 already documented a stranded submission as terminal; the status is now the same
    from every such verb.
  • The serialization rule is complete. Every call that resets or submits on a device, and every
    blocking sslm_gpu_ready, must be externally serialized against every other such call on that
    device. The header named three calls (the two decodes and the blocking sslm_gpu_ready); it now
    lists every one, among them sslm_gpu_model_map, sslm_gpu_adapter_map, sslm_gpu_seq_create,
    sslm_gpu_seq_restore, the prefill and finish bridges, and the new pool, prefix, adopt and restore
    verbs. A host that already serializes every GPU call needs no change. Non-blocking
    sslm_gpu_ready may still run beside a submitter.
  • The order of two refusals is now documented. SslmGpuSeqPrefillSchemaContentForG5Bridge on a
    Submitted sequence returns SSLM_BUSY before it checks the first token's reachability
    (SSLM_SEQUENCE_REJECTED). That order is unchanged since 1.6.0; the header now states it, with the
    order of every guarded verb's refusals.
  • SslmGpuStatus gains ordinals 24 to 29 (above). Only pooled sequences, prefixes and the pool
    verbs return them, except SSLM_GPU_HOLDER_MODE_MISMATCH, which sslm_gpu_seq_restore returns for
    an SLM6 blob. A host that switches over the enum should add them.
  • No-budget CPU saves of blocks of 16 MiB or more on x64 are faster than 1.12.0's, with the same
    bytes; a full-length save still reads slower than 1.11.0's (see Speed).
  • No existing declaration, struct layout or ordinal of gpu_1p0.h changes; its additions are new
    declarations and appended enumerators. The CPU C ABI does not change.
  • The internal layer, superslm/gpu_port.h, does change. It is installed with the other headers,
    and three of its existing declarations changed signature: RunLayerLoopGpuSubmit and
    SubmitChunkToFullDepthForG5Bridge hand their in-flight work out through a GpuInFlightToken*
    where they took a GpuLayerLoopInFlight**, and each gains a trailing, defaulted paged_kv
    parameter; RunLayerLoopGpuFinish takes a GpuInFlightToken&& where it took a
    GpuLayerLoopInFlight*. Code that calls them as 1.12.0 declared them does not compile against
    1.13.0. The layer also refuses a reset on a device whose last submission is unobserved, by
    throwing harness::PoolSubmitContractError before anything is reset, and one on a stranded
    device with harness::GpuSubmissionStrandedError (gpu_1p0.h, In-flight work, states its
    duty). A host that uses only gpu_1p0.h is not affected.

A host that adopts GPU pools should know:

  • An SLM6 blob cannot be read by 1.12.0 or earlier: their sslm_gpu_seq_restore refuses it on its
    magic with SSLM_SEQUENCE_KV_BUFFER_MISMATCH and creates no sequence (cell 9.8, on the release
    machine, at commit 845918e, with a reader built from 5d5ca58, a 1.12.0 development commit
    before the v1.12.0 tag: its src/gpu/ is identical to the tag's, but the host-side forward and
    integer-math files the GPU finish uses differ; the tag's own restore refuses SLM6 on its magic in
    the same code). At 05e09d8 the cell's first leg read 21 checks and its old-reader leg 14, 0
    failures.
  • Pass an SLM6 blob to sslm_gpu_seq_restore_into_pool, not sslm_gpu_seq_restore. Pass each
    restore its live prefix handle: without it a restored sequence holds its prefix span privately
    until it resets or re-adopts (the 5,592 pages above, against 1,842).
  • The pool, prefix, adopt and restore-into-pool verbs that submit GPU work return SSLM_BUSY while
    any sequence in the process is Submitted, and a guarded verb called on a dedicated sequence
    returns SSLM_BUSY while a pooled one is Submitted. A host that mixes pooled and dedicated
    sequences should finish each submission before the next call, as above.
  • Size admissions from sslm_gpu_kv_pool_stats' free pages, not from handle counts: a shared page
    stays counted until every holder that maps it lets go.
  • An adopt of a prefix from another pool of the same model, or onto a dedicated sequence, is refused
    (SSLM_GPU_PREFIX_REJECTED, SSLM_GPU_HOLDER_MODE_MISMATCH); a prefix of another model's pool is
    refused with SSLM_SEQUENCE_KV_BUFFER_MISMATCH.
  • A prefill into a pooled sequence that reaches its limit returns SSLM_GPU_KV_BUDGET_EXCEEDED
    after committing the tokens below the limit. The prompt bridge reports no count: the committed
    tokens are as many as the budget had room for, and the next bridge decode finishes the last of
    them instead of embedding its token argument.

Not in this release

  • The AMD Radeon RX 7900 XTX. The paged GPU surface, and the fixes in this release, are run and
    measured on the NVIDIA card only (see Verification).
  • Memory savings for dedicated GPU sequences. sslm_gpu_seq_create keeps one whole-cap buffer
    per sequence, and its SLM5 save is the whole buffer.
  • A larger GPU page. The GPU page stays kv_block_size, 16 positions for converted artifacts. A
    larger page was the fallback had paged decode missed its bar; it did not.
  • A removed cap, automatic prefix matching, adapter-shaped prefixes and batched shared-prefix
    attention
    , as in 1.12.0.
  • Cross-backend blobs. A GPU blob does not restore on the CPU, nor a CPU blob on the GPU.

Verification

The cell numbers in this note name cells in tests/paged-kv-gpu/ (and, for 9.3s, tests/paged-kv/);
each source file lists its cells in its header.

  • Software GPU (Linux, Wine with vkd3d-proton over lavapipe, tools/cloud_gpu/): the GPU red
    suite ran with 106 jobs green and 17 red, each red one in a class the software GPU cannot run (the
    D3D12 debug layer, a real model artifact, an adapter file). It was not re-run in full after the
    last development fixes (the prefix release fix and the page-table state fix above); a
    resource-state checker compiled into the software-GPU build counted 0 violations in the prefix
    cells after the page-table fix, against 24,446 before it. superslm_tests ran there in full with 0 failures after the page-table addressing
    change (129,188 checks), and the shaders compile with warnings as errors.
  • Software GPU, after the adversary review's fixes (the same runner, tiny fixtures, so a smoke
    run, not a certification): superslm_tests in full, 129,248 checks, 0 failures; the new race cell
    pkvg_same_handle_race, 197 checks, 0 failures (before the claim was widened it failed 20 of 149,
    and its counters leg failed before the counts were atomic); the t2112 same-handle cell, 289
    checks, 0 failures.
  • Release machine, NVIDIA GeForce RTX 2080 SUPER (adapter 0, Windows x64, D3D12). build.bat
    built the branch at 732ee90, and every suite executable was rebuilt at 6bd674b, the commit the
    release text was written on. After it came a build-script option for the GPU red suite's Windows
    build (a8ee139), the release text and the version (37a2348, which also changed the install
    consumer's version), a test-instrumentation fix in the GPU allocation-order suite (d8355e6),
    and the fixes from the adversary review of this contract: the same-handle claim widened to the
    bridge decode and the finish, the live-handle counts made atomic, and a new race cell. Those
    last fixes change library code. Between f45e642, after them, and the branch head, the GPU
    library changed only in the buffer names it sets under the debug layer, the resource-state
    checker compiled into test builds and a header comment, and the CPU library only in a comment;
    the library code has not changed since e30db83. Read there:
    • at 05e09d8, the branch head before the final release-text commits, debug layer on:
      superslm_tests with its GPU cells, 129,251 checks, 0 failures (build.bat exit 0), including
      the paged-KV GPU ledger cells (12 cells, 93 checks); the page-table cell 6.5a against the
      reference record below, 364 checks and 0 debug-layer messages; cell 9.8, 21 checks, and its
      old-reader leg, 14; the real-artifact legs of cells 10.3, 10.5 and 10.7 (280, 217 and 793
      checks); and the paged-KV CPU suites (see CPU); 0 failures in every one;
    • at f45e642 or a later commit, debug layer on unless noted: the new race cell (every pairing of
      the four decode entry points, on a dedicated and a pooled handle) and the t2112 same-handle cell,
      289 of 289; the GPU batched-prefill suite (t2178), all five cells, in both modes; the GPU
      allocation-order suite (te436), 368 green and 0 invalid sites, its commissioning pair accepting
      and rejecting as required (the 8 invalid sites read earlier were the suite's own record growing
      during its counting pass, fixed at d8355e6); the fixture legs of cells 10.3, 10.5 and 10.7;
      the debug-layer watchdog cell 3.12, five runs, with its three mutants caught by the host
      resource-state checker rather than by the debug layer; the pool-ceiling cell 11.4 with its three
      mutants killed; the 19 API-failure hook jobs (debug layer off, by design) and the zero-fill legs
      of cells 11.3 and 11.4; cell 1.9 in the prefix and save runners (4,125 checks each, no fault);
      and cells 4.8, 6.5b and 8.14 to 8.16 in the G2 to G5 runners;
    • at e30db83: the forced-tier legs of build.bat, green, and the FP-free ship gate, PASS, with
      movntdq on its allow list (the streaming store, above);
    • at 6bd674b: the t2112 same-handle cell (two sslm_decode_step_gpu calls on one handle), 289
      checks, 0 failures, with the debug layer on and off; the GPU allocation-status suite with the
      debug layer off, 411 green, across its injection runs;
    • before the last fixes, on the builds from 732ee90 to 845918e: superslm_tests with its GPU
      cells (read again at 05e09d8, above), the GPU prefill-read suite (t2791) and the GPU
      allocation-status suite (te425) with the debug layer on, all green; the reference record the
      page-table cell compares the new build with, taken at 63e7b0e, this branch's build before the
      page-table change, 190 of 190 (the comparison against it passed at 05e09d8, above; it checks
      against this branch's earlier build, not against a 1.12.0 build);
    • at 845918e, debug layer on: the save and restore cells (9.6, 9.12 over its full 240 cases,
      9.13, 8.17, the save at the cap, and both legs of 9.8), cells 10.3, 10.5 and 10.7 on the fixture
      and on the real Qwen2.5-0.5B artifact, the pool-ceiling cell's three mutants (each killed, and
      again at 6bd674b), the concurrent decode test, and the 15 API-failure hook jobs (debug layer
      off), all green.
    • Still open. The cross-vendor battery reads red, in two cells whose pins are stale and in
      two smoke cells; the reds predate this release's GPU changes (the page-table addressing
      onwards), and the battery is not a check of this release until they are refreshed.
    • Debug-layer resource-state messages, explained. The D3D12 debug layer reported
      resource-state errors in the prefix and restore cells at 845918e; the page-table class was an
      engine fault and is fixed (above). The other messages appear only when cell 1.9 runs earlier in
      the same process: after the last library change, one selection of the prefix runner read 8,855
      messages in that order and 0 without cell 1.9. The same selection, in the same order, under the
      host resource-state checker (every barrier, copy, dispatch-binding and buffer-lifetime class,
      use after release included) read 0 violations across 2,277,760 buffers, so the messages are
      recorded as an artifact of the validation layer, not an engine fault. The two cells that read
      red in that run did so on the clean-layer check only; every functional check passed.
    • Submission-fault mutants (t2956). Their evidence was regenerated at f73fc3b, after fixes
      to the mutant tooling: the unmutated build passes, 26 production mutants are killed, one (c) is
      a semantic proxy, and four (a, b, b2, c_exact) have no target left since the decode-threading
      rewrite.
  • Old reader: cell 9.8, both legs, at 845918e and at 05e09d8 (above): the reader built from 5d5ca58 (see
    Compatibility) restores the dedicated SLM5 control with the recorded continuation and refuses
    the SLM6 blob.
  • AMD Radeon RX 7900 XTX: not run. The card is on a separate machine, and this release
    certifies the paged GPU surface on the NVIDIA card only. The AMD legs (superslm_tests with the
    GPU cells, the cross-vendor battery, the GPU red suite per step, and cells 10.3, 10.5 and 10.7) are
    a known gap, to run there before any AMD statement is made.
  • Linux x64 (GCC 13, Release), at the release-text commit: superslm_tests, 123,802 checks, 0
    failures (the GPU backend is not built on Linux), and the install consumer configures and builds
    against the installed package at version 1.13.0. Again after the adversary review's fixes:
    123,802 checks, 0 failures.
  • CPU: the no-budget save fix adds cell 9.3s to superslm_pkv_c4 (the streaming path forced on
    every block, against the pinned 1.11.0 blobs, with 9.1's resting and mid-token states streamed
    against plain). The lifecycle cell is green on the release machine at e30db83, 66 checks (see
    Speed). At 05e09d8 on the release machine the paged-KV CPU suites pass with 0 failures:
    superslm_pkv_r0 (5 cells, 441 checks), superslm_pkv_c2 (7 cells, 4,021), superslm_pkv_c3 (6
    cells, 114), superslm_pkv_c4 (31 cells, 5,793; one cell more than 1.12.0's, 9.3s) and
    superslm_pkv_c5 (70 cells, 74,052), and superslm_pkv_c5 again with the SSE2 tier and with the
    AVX2 tier forced (70 cells, 74,053 checks each). The release machine (AMD Ryzen 9 3950X) has no
    AVX-512, so superslm_pkv_c5 with the AVX-512 tier forced ran on a Linux x64 host with an Intel
    Xeon (GCC 13.3, Release): the tier leg (cells 4.7/C5 and 6.3/C5) 521 checks, the whole suite 70
    cells, 72,847 checks, 0 failures, with the AVX-512 kernels confirmed entered under a debugger. Of
    the 1.12.0 review's box-owed tests against the MSVC lifecycle binary, the
    refusal tests passed (15) at f45e642 or later, and the timing-lock and real-geometry tests
    passed at 6bd674b; the CPU library has changed since only in a comment.
  • Suites (CI): superslm_tests runs on Windows x64, Linux x64, Linux x64 with AddressSanitizer and
    UndefinedBehaviorSanitizer, Linux x64 Debug, macOS arm64 and, under ThreadSanitizer, Linux x64,
    with the forced-tier, digest and source-check legs; what the hosted matrix executed for this release
    is stated in docs/platform-support.md's CI section, per that document's rule.
  • Code review: each of the pool, prefix and save steps was reviewed by a reviewer that did not
    write it, and every blocking and should-fix finding was fixed. The final review of the release
    diff, at 6bd674b, found no blocker and read it as ready to ship; it predates the adversary
    review's fixes and the later changes listed above.

Principal files changed

  • include/superslm/gpu_1p0.h: the pool, prefix and restore-into-pool verbs, the two handle types,
    the six statuses, the in-flight promises and the serialization list.
  • src/gpu/gpu_1p0.cpp, src/gpu/superslm_gpu.cpp, src/gpu/d3d12_harness.h,
    include/superslm/gpu_port.h: the pool, budgeted sequences, prefixes, adopt, SLM6, the per-handle
    decode claim and the guards.
  • src/gpu/submission_ledger.h, src/gpu/gpu_inflight_token.h, src/gpu/gpu_inflight_registry.*,
    src/gpu/gpu_call_timing_snapshot.h: the submission ledger and in-flight tracking.
  • src/gpu/gpu_kv_pool_geometry.h, src/gpu/shaders/kv_page_addr_model.h, src/gpu/shaders/:
    the page geometry, the page-table addressing in the shaders, and the barrier fix.
  • src/gpu/gpu_resource_state_tracker.h: a resource-state checker compiled only into test builds.
  • src/sslm_abi.cpp: the streaming no-budget save.
  • src/forward/parallel_split.cpp: the host parallel-for call site carries the GPU in-flight tracking
    into hook tasks.
  • tests/paged-kv-gpu/, tools/cloud_gpu/, tools/run_paged_kv_g6_box.ps1: the GPU cells, the
    software-GPU runner and the timing runner.
  • CMakeLists.txt, tests/install-consumer/CMakeLists.txt, README.md, CHANGELOG.md,
    docs/api.md, docs/sslm_format.md and this note: version 1.13.0.