spec(KERNEL-SSM-MAMBA): the Mamba2 SSD core was never built, only the GDN arm (#496) - #502
Merged
Merged
Conversation
… GDN arm (#496) FOLLOWING_AGENTS_PROTOCOL The row is titled "General Mamba selective scan, causal convolution, SSD, and linear attention kernels". Only the second and fourth clauses were ever built. Everything landed under it is the GDN arm: the gated-delta-rule recurrence, its causal conv, its state gather/scatter, the sm_120 tiling campaign. The matrix row already conceded it in passing, four times, and the concession is easy to read as a scoping note rather than as an absent capability: "these GDN tests do not prove generic Mamba support". They do not, and the distance is not small. Gated delta rule carries the (I - beta k k^T) removal term and a per-head scalar decay; Mamba2's SSD is a diagonally-decayed gated linear recurrence driven by A_log / dt / D, with B and C shared across n_groups head groups. include/vt/ops.h has kCausalConv1dFwd, kCausalConv1dUpdate, kCausalConv1dSpecUpdate, kRmsNormGated, kGdnPrefill, kGdnDecode and kKdaGatedDeltaRule, and no chunked state-space scan and no selective state update at all. kGdnPrefill cannot be reshaped into one. What this costs: ten INVENTORIED model rows wait on this single kernel -- NemotronH, Mamba2, GraniteMoeHybrid, FalconH1, Zamba2, Jamba, Lfm2, Lfm2Moe, Plamo2, OlmoHybrid. The immediate driver is nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-NVFP4 (23 mamba / 6 attention / 23 MoE, n_groups=8, ssm_state_size=128, chunk_size=128), which is 20.1 GiB and fits one GB10. The pinned oracle already runs that arch -- registry.py:179 -> nemotron_h.py, MambaMixer2 at nemotron_h.py:373, NemotronHMoEDecoderLayer at nemotron_h.py:317, ModelOptMixedPrecisionConfig at modelopt.py:2280 -- so the gap is entirely ours, and the SSD core is the part not reachable by composing what we already have. The spec is host-reference-first, mirroring the KDA and DeepSeek-V4 DSA lanes: W1 lands portable CPU references for the chunked scan, the single-token selective update and the silu-gated GROUP RMS norm (a sibling of our sigmoid kRmsNormGated, not a parameter of it), gated against a from-first-principles double-precision reference. Two tests upstream does not have carry the weight, because chunk cumsum, state passing and the scan combine are each plausible and jointly wrong in ways one chunk cannot see: chunked-must-equal-sequential, and chunk-boundary invariance across chunk_size in {8,16,32,64,128}. No lifecycle state moves and no measurement is claimed. The row stays INVENTORIED: the spec is committed, the implementation has not started, and W1 goes to a fresh implementer. FEATURES.md gains a "Inventoried but blocked" row because the honest reason differs from the other three entries there -- Nemotron-H fits the pool, so it is capability-blocked, not hardware-blocked, and the page should not imply we are waiting on a bigger box. Records and docs only, no product code touched. Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
localai-bot
pushed a commit
that referenced
this pull request
Aug 12, 2026
…yed records reconciled BY HAND (#339, #365) Step 3, the forward merge. main moved 7 commits past the 37cab97 this branch was cut from while steps 1 and 2 were being built and gated (SPEC-DSPARK #442 x4, KERNEL-SSM-MAMBA-SSD #496/#502 x3). Those 7 commits touch RECORDS AND DOCS ONLY -- no src/, include/ or tests/ file moves -- so the CPU gate taken on 3111fb2 still describes this tree exactly. Asserted, not assumed: `git diff 3111fb2 -- src include tests` is EMPTY, so the 396/396 ctest result and the three focused counts in 3111fb2's message were produced by a byte-identical code tree. SIX KEYED RECORDS, RECONCILED BY HAND. `git merge` raised a marker in exactly one of them, which is precisely the case AGENTS.md says not to trust: an automatic three-way merge of a keyed record is refused whether or not it conflicted. All six were taken from origin/main WHOLESALE -- each one blob-hash-verified byte-identical to `origin/main:<path>` BEFORE any edit -- and this row's scoped edits reapplied by a script that asserts every anchor is UNIQUE (count == 1), never merely present: .agents/roadmap_v1.md 6 rows (#467, #339, #402, #468, #501, #469), each after its own unique anchor row, in the owning branch's order. Post-condition asserted: all 9 touched keys appear exactly once. .agents/kernel-matrix.md 1 changed cell (`KERNEL-GEMM-FP8`); the pre-edit line is still unique on main. .agents/benchmark-record.md CONFLICTED. Genuinely append-only by its own header, so union-appended: main's entries first and untouched, this row's PERF-GDN-PACKED-BRIDGE section after. Verified as a PURE APPEND -- the diff against origin/main has 65 added lines and ZERO removed. docs/BENCHMARKS.md 1 added `Lever 2b` row after a unique anchor. docs/STATUS.md 1 added 11-line PERF-GDN-PACKED-BRIDGE block after a unique two-line anchor. docs/FEATURES.md this row's block, rewritten to fit -- see below. VERIFIED KEY BY KEY after reapply: each of the six differs from `origin/main:<path>` by this row's own added lines and by NOTHING else. No unrelated key changed, was removed, or was duplicated. The three files main touched that this row does not (`.agents/model-matrix.md`, `specs/dspark-spec-decode.md`, the new `specs/mamba2-ssd.md`) are single-sided, so no merge occurred at all; each is blob-verified identical to origin/main. docs/FEATURES.md -- THE CAP FORCED A REWRITE OF THIS ROW'S OWN ENTRIES, and the arithmetic is worth recording because it is the #460 failure mode happening live. Sizes in CHARACTERS, which is what `check-public-doc-tables.py` counts (the file is 30,690 BYTES; the marks are multi-byte): 37cab97 29,053 the base this branch was cut from e6e1122 29,335 main grew +282 under us (one Nemotron-H row, #496) this row +917 the five entries steps 1-2 carried --------------------------------------------------------------- naive 30,252 OVER the 30,000 cap by 252 Nothing belonging to another row may be evicted to fix that, so the whole 252 came out of THIS ROW'S OWN five entries, which are now four. Two pairs were folded, and in both cases the fold is more accurate than the split it replaces: - `VT_GDN_FP8_IN_BF16` and `VT_GDN_PACKED_DECODE_FP8_TOWER` became ONE row, because the bridge's own review established they are NOT independent -- the packed toggle is inert without the bf16 one (#491). Two keys implied a composition that does not exist. - the split-K refusal joined the epilogue-alpha row: `claims_splitk1_premise` is a property OF that fp8 cuBLASLt GEMM, not a separate user-facing surface. - `| fp8 weights |` returns to main's bare form; the packed-decode capability it had been overloaded onto now lives on the row that actually owns it. No FACT was dropped, only relocated to the surface AGENTS.md says owns it: the gross-defect-only gate strength, the "not equivalence" caveat and the 0.977x -> 0.984x measurement are all carried in full by the docs/STATUS.md block and .agents/benchmark-record.md entry this same merge preserves. FEATURES is a capability matrix; measurements were never supposed to live there. Result 29,962 of 30,000, 38 chars of headroom. That headroom is the debt, not the fix: the NEXT row to touch this page hits the same wall. Recorded on #460. GATES on this tree. `scripts/agent-preflight.sh --staged` exit 0. check-snapshot-pins, check-doc-checkpoint and check-public-doc-tables all exit 0 standalone. Trailers checked over the full consolidation range. The CPU tier was NOT re-run for this step and does not need to be: the code is byte-identical to 3111fb2, which was configured, built (build_exit=0, zero warnings, zero errors, no ENOSPC markers) and ctested SERIALLY at 396/396, CTEST_EXIT=0. STILL OWED, and owed to the operator, not silently assumed: everything on the CUDA tier. This host has no nvcc and no GPU, so `test_ops_fp8_cutlass` runs 8 cases and ZERO assertions -- every one prints "no CUDA device; skipping". The ulp bound this consolidation exists to deliver is present in the file and UNEXECUTED here. Both toggles stay DEFAULT OFF; no default flip and no new measurement is argued anywhere in these three merges. No GPU work was queued on dgx.casa. Issue: #339 Issue: #365 FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: Claude:claude-opus-5 [ClaudeCode]
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.
Closes part of #496 (the spec half; the issue stays open until W1 lands).
What this is
W0 for
KERNEL-SSM-MAMBA: the committed spec for the Mamba2 SSD core, plusthe record edits that make the gap visible where someone would actually look
for it.
No lifecycle state moves. No measurement is claimed. No product code is
touched. The row stays
INVENTORIED; W1 goes to a fresh implementer.The gap
The row is titled "General Mamba selective scan, causal convolution, SSD, and
linear attention kernels". Only the second and fourth clauses were ever built.
Everything landed under it is the GDN arm. The matrix row already conceded
this in passing — "these GDN tests do not prove generic Mamba support" — but
it reads as a scoping note rather than as an absent capability, and it is
repeated at four checkpoints without ever being costed.
Gated delta rule is not Mamba2. GDN carries the
(I − β kkᵀ)removal term anda per-head scalar decay; Mamba2's SSD is a diagonally-decayed gated linear
recurrence driven by
A_log/dt/D, withBandCshared acrossn_groupshead groups.include/vt/ops.hhaskCausalConv1dFwd,kCausalConv1dUpdate,kCausalConv1dSpecUpdate,kRmsNormGated,kGdnPrefill,kGdnDecode,kKdaGatedDeltaRule— and no chunkedstate-space scan and no selective state update.
Ten
INVENTORIEDmodel rows wait on this one kernel: NemotronH, Mamba2,GraniteMoeHybrid, FalconH1, Zamba2, Jamba, Lfm2, Lfm2Moe, Plamo2, OlmoHybrid.
Immediate driver
nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-NVFP4— 52 layers, 23 mamba /6 GQA attention / 23 MoE,
n_groups=8,ssm_state_size=128,chunk_size=128,20.1 GiB, fits one GB10. The pinned oracle already runs the arch
(
registry.py:179→nemotron_h.py;MambaMixer2atnemotron_h.py:373;NemotronHMoEDecoderLayerat:317;ModelOptMixedPrecisionConfigatmodelopt.py:2280), so the gap is entirely ours.Approach
Host-reference-first, mirroring the KDA and DeepSeek-V4 DSA lanes. W1 lands
portable CPU references for the chunked scan, the single-token selective update
and the silu-gated group RMS norm (a sibling of our sigmoid
kRmsNormGated, not a parameter of it), gated against a from-first-principlesdouble-precision reference.
Two tests upstream does not have carry the weight, because chunk cumsum, state
passing and the scan combine are individually plausible and jointly wrong in
ways a single-chunk test cannot see:
chunk_size ∈ {8,16,32,64,128}.RED first, with the reviewer mutating each claimed guarantee in a scratch copy.
Files
.agents/specs/mamba2-ssd.md.agents/roadmap_v1.md.agents/kernel-matrix.mdKERNEL-SSM-MAMBAcheckpoint naming the SSD gap; lifecycle unchanged.agents/model-matrix.mddocs/FEATURES.mdscripts/agent-preflight.sh --staged: All gates green.🤖 Generated with Claude Code