Skip to content

spec(KERNEL-SSM-MAMBA): the Mamba2 SSD core was never built, only the GDN arm (#496) - #502

Merged
localai-bot merged 1 commit into
mainfrom
row/KERNEL-SSM-MAMBA-SSD
Aug 12, 2026
Merged

spec(KERNEL-SSM-MAMBA): the Mamba2 SSD core was never built, only the GDN arm (#496)#502
localai-bot merged 1 commit into
mainfrom
row/KERNEL-SSM-MAMBA-SSD

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

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, plus
the 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 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, kKdaGatedDeltaRule — and no chunked
state-space scan and no selective state update.

Ten INVENTORIED model 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:179nemotron_h.py; MambaMixer2 at nemotron_h.py:373;
NemotronHMoEDecoderLayer at :317; ModelOptMixedPrecisionConfig at
modelopt.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-principles
double-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:

  • chunked == sequential against an independent double-precision recurrence;
  • chunk-boundary invariance across chunk_size ∈ {8,16,32,64,128}.

RED first, with the reviewer mutating each claimed guarantee in a scratch copy.

Files

File Why
.agents/specs/mamba2-ssd.md new spec (W0)
.agents/roadmap_v1.md issue-table entry for #496
.agents/kernel-matrix.md KERNEL-SSM-MAMBA checkpoint naming the SSD gap; lifecycle unchanged
.agents/model-matrix.md NemotronH row records its blocker and the three further things it owes
docs/FEATURES.md "Inventoried but blocked" row — Nemotron-H is capability-blocked, not hardware-blocked, and the page should not imply we are waiting on a bigger box

scripts/agent-preflight.sh --staged: All gates green.

🤖 Generated with Claude Code

… 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
localai-bot merged commit 0c69f0e into main Aug 12, 2026
22 of 24 checks passed
@localai-bot
localai-bot deleted the row/KERNEL-SSM-MAMBA-SSD branch August 12, 2026 17:04
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]
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.

2 participants