Skip to content

Commit 3dd490a

Browse files
committed
merge: origin/main into row/LTX25-T2A-ONE-STAGE -- the index taken from main
Four commits landed while this row was in CI: `283c7e492` (#1051), `e34d71379` (#1054), `0f8580e26` (#1043) and `b493f4981` (#1035). None touches a `src/`, `include/` or `tests/` file this row touches -- the only overlaps are `CMakeLists.txt`, the two keyed public records, and the issue index. `.agents/issue-index.md` was rebuilt rather than merged: `origin/main`'s file taken wholesale with this branch's own 8 rows re-appended (#1005, #1013, #1031, #1039, #1048, #1049, #1050, #1052), then verified -- main's bytes are a byte-identical prefix, and 283 rows carry 283 unique ids. The union driver's clean result is not trusted here: on a sibling branch today it interleaved rows at a measured byte offset and, separately, reinstated a row `main` had deleted. `CMakeLists.txt` merged to a single added line and still carries exactly one `ltx2_t2a` reference, so the new translation unit is registered once. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code]
2 parents b70f630 + b493f49 commit 3dd490a

65 files changed

Lines changed: 6358 additions & 178 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/backend-matrix.md

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

.agents/benchmark-record.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21994,3 +21994,100 @@ needs both the explicit batched reads and the cache hit rate together. The
2199421994
pieces are in tree and unwired: `ExpertSlotCache`, `GgufExpertSpanOf` and
2199521995
`ExpertStreamer`. See [`.agents/specs/expert-streaming.md`](../.agents/specs/expert-streaming.md).
2199621996

21997+
21998+
## MUSIC3-DEVICE-ARM — MiniMax-Music3 on Jetson Thor, CPU vs accelerator, both arms same box and same binary (2026-08-16, `row/MUSIC3-DEVICE-ARM`, base `origin/main` `c07526aa1`, Thor sm_110, #672)
21999+
22000+
**Not a parity ratio.** There is no reference leg here: SGLang-Omni is
22001+
`gateable = no` and its production configuration is CUDA-graphed and compiled,
22002+
while five of our six stages are scalar host loops. This is an INTERNAL two-arm
22003+
number about a PARTIAL device arm, and every axis in `docs/BENCHMARKS.md`
22004+
against the reference stays `PENDING`.
22005+
22006+
### Recipe
22007+
22008+
Host `kairos-4db2` (`192.168.68.23`), Jetson Thor **sm_110**, aarch64, 14 cores,
22009+
~122 GB unified, driver 595.78, Ubuntu 24.04 under Kairos. Image
22010+
`vllmcpp-thor:cuda13.0.1` (nvcc 13.0.88), run
22011+
`sudo -n docker run --rm --runtime=nvidia -e NVIDIA_DISABLE_REQUIRE=1`
22012+
— `--gpus all` is refused outright by the hook, and `NVIDIA_DISABLE_REQUIRE=1`
22013+
is required because the image's `NVIDIA_REQUIRE_CUDA` tops out at `driver<576`.
22014+
22015+
cmake -S . -B build-cuda -G Ninja -DCMAKE_BUILD_TYPE=Release \
22016+
-DVLLM_CPP_CUDA=ON -DVLLM_CPP_CUDA_ARCHITECTURES=110 \
22017+
-DVLLM_CPP_TRITON=OFF -DVLLM_CPP_SERVER=ON # no cutlass
22018+
22019+
Checkpoint `MiniMaxAI/MiniMax-Music3` diffusers arm, mounted read-only from
22020+
`/usr/local/nas_share/checkpoints/minimax-music3`. Source moved with
22021+
`git archive`, never rsync. Each run took `flock $HOME/gpu.lock` for its whole
22022+
duration, so no two arms overlapped, and ONE checkpoint was resident at a time —
22023+
this box has `vm.overcommit_memory=1` with zero swap and reboots instead of
22024+
OOM-killing.
22025+
22026+
minimax-music3-gen --model /nas/checkpoints/minimax-music3 --out <wav> \
22027+
--lyrics '[Verse]\nMorning light through the pines' \
22028+
--description 'Genre: acoustic pop. BPM: 96. Key: C major.' \
22029+
--duration <0.1|0.4> --steps 2 --seed 7 --device <0|1>
22030+
22031+
### Wall clock
22032+
22033+
| request | AR frames | delivered | `--device 0` CPU | `--device 1` CUDA | ratio dev/cpu | load before -> after (cpu) | (cuda) |
22034+
|---|---|---|---|---|---|---|---|
22035+
| `--duration 0.1` | 2 | 0.070 s, 3072 samples/ch | **835.1 s** | **846.6 s** | **1.014x SLOWER** | 4.29 -> 4.87 | 3.96 -> 6.78 |
22036+
| `--duration 0.4` | 10 | 0.395 s, 17 408 samples/ch | **1512.1 s** | **1430.4 s** | **0.946x** | 4.00 -> 5.29 | 3.31 -> 4.72 |
22037+
22038+
`vmstat` showed the box 99 % idle before the series and no other container ran.
22039+
Runs were alternated (cuda, cpu, cuda, cpu) rather than grouped.
22040+
22041+
### Attribution — the difference is what isolates the language model
22042+
22043+
Every stage except the 8.6B LM is the same host code on both arms, so it cancels
22044+
in `D(n) = T_cuda(n) - T_cpu(n)`:
22045+
22046+
D(2) = +11.5 s D(10) = -81.7 s
22047+
slope = -11.65 s per AR frame
22048+
intercept = +34.8 s => break-even at ~3 AR frames (~0.12 s of audio)
22049+
22050+
**Two points determine a line exactly**, so this is a fit with no residual and no
22051+
error band. It is an attribution, not a bound; a third duration is owed before
22052+
anything stronger is claimed.
22053+
22054+
The fixed cost is CONSISTENT WITH the one-time host->device upload of the 8.6B
22055+
model (`ResidentWeight`, 17.2 GB) plus context creation. **That was not measured
22056+
separately** and is recorded as the plausible reading rather than as a result.
22057+
22058+
### Why the ratio is small, and why that is the honest headline
22059+
22060+
`--device 1` moves ONE of six stages. The profile this row inherited
22061+
(`.agents/specs/minimax-music3.md` §"Now", `perf record -g`, 173 K samples) puts
22062+
`LinearNoBias` — the RVQ depth decoder, a scalar host triple loop under
22063+
`-ffp-contract=off` — at 42-57 % of the autoregressive half, and
22064+
`vocoder1d::ConvTranspose1d` at 88.5 % of the acoustic half. Neither takes a
22065+
queue. The vocoder cannot take one yet at all: **`vt` has no `ConvTranspose1d`
22066+
op**, and `vt::Conv2d` / `vt::DepthwiseConv1d` are registered CPU-only
22067+
(`src/vt/cpu/cpu_conv2d.cpp:111`, `src/vt/cpu/cpu_conv1d_depthwise.cpp:95`), so
22068+
there is no CUDA kernel behind any op that stage could route through.
22069+
22070+
### The correctness leg, same box and same binary
22071+
22072+
`test_minimax_music3_llm_real` with `VLLM_CPP_MUSIC3_DEVICE` 0 and 1, 25
22073+
teacher-forced steps vs `frame_hiddens[:, :4096]`, 102 400 values, at the bounds
22074+
that were already there — **no tolerance was widened for the device arm**:
22075+
22076+
| arm | bit-identical | mean\|d\| | outside 2 bf16 ULP | golden-code mean rank | negative control |
22077+
|---|---|---|---|---|---|
22078+
| Thor CPU | 9337 (9.118 %) | 1.76348e-02 | 37 572 (36.69 %) | 2.48 | mean\|d\| 0.802531, 98.20 % outside |
22079+
| Thor CUDA | 9324 (9.105 %) | 1.71668e-02 | 36 509 (35.65 %) | 2.44 | mean\|d\| 0.802583, 98.18 % outside |
22080+
| control (torch `sdpa_kernel(MATH)`, recorded) | 12 036 (11.75 %) | 1.475e-02 | 29 968 (29.27 %) | — | — |
22081+
22082+
Both 4 cases / 220 assertions / 0 failed. The CUDA arm is marginally CLOSER to
22083+
the golden than the CPU arm, and both are inside the measured torch-vs-torch
22084+
control. The negative control fires identically on both, so the bound still
22085+
discriminates rather than having gone slack. **The Thor CPU arm reproduces the
22086+
x86-64 numbers this row recorded in 2026-08-15 value for value**, which is the
22087+
CPU path being unchanged across two architectures rather than on one box.
22088+
22089+
**The two arms produce DIFFERENT SONGS and that is structural, not a defect**:
22090+
spec §5 withdrew the token gate because the AR codes are a seeded
22091+
`torch.multinomial` draw, so a different logit changes the drawn code and
22092+
everything downstream. Sample-wise comparison of the two WAVs is meaningless and
22093+
none is offered; the RMS/peak of each run are recorded in the spec instead.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# CLAIM-SPEC-MTP-K-GT-1
2+
3+
| Claim | Row IDs | Agent | Worktree / remote dir | Branch | Owned scope | State | Last update |
4+
|---|---|---|---|---|---|---|---|
5+
| `CLAIM-SPEC-MTP-K-GT-1` | `SPEC-MTP-K-GT-1` (`ACTIVE`) | Claude Code (opus-5), helper role | isolated worktree `/home/mudler/.cache/sdd/mudler-vllm.cpp/mtp-k`; CPU only, GPU lock held by another session throughout and NOT taken | `row/SPEC-MTP-K-GT-1`, issue [#81](https://github.com/mudler/vllm.cpp/issues/81) | Owns ONLY the MTP speculation-DEPTH path: NEW `.agents/specs/mtp-k-gt-1.md`; NEW `prepare_decode_inputs.{h,cpp}`; `MtpProposeDrafts` in `spec_decode/mtp/speculator.{h,cpp}`; `Qwen3_5MTPModel::GatherHiddenRows`; `GPUModelRunner::propose_drafts` + the per-depth acceptance counters; the `mtp` arm of `LoadedEngine::ResolveSpecConfig` and the in-memory `mtp_weights` seam; the three new test suites. EXCLUDES the n-gram, DFlash and DSpark proposers, the GDN speculative rollback, the CUDA-graph predicate and slot key ([#1020](https://github.com/mudler/vllm.cpp/issues/1020), owed not fixed), and every depth POLICY (dynamic and adaptive stay out of scope) | `ACTIVE` | 2026-08-16 — depth configurable and CPU-gated at k=1..4 (ctest 493 passed / 0 failed / 2 skipped of 495, exit 0; the two skips are checkpoint-gated and unrelated: `test_modelopt_mixed_precision_checkpoint`, `test_voxtral_e2e`); the DGX three-way at k=2..4 and the matched-k throughput A/B are OWED, so no speed number is claimed above k=1 |

.agents/engine-matrix.md

Lines changed: 3 additions & 2 deletions
Large diffs are not rendered by default.

.agents/environment.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,21 @@ inner 4096, state 128; context 262144.
431431
only `GL_KHR_cooperative_matrix`, and the build still configures and runs. A
432432
source-built shaderc `v2026.4-dev` lives at `/tmp/shaderc/b/glslc/glslc`; pass
433433
`-DVulkan_GLSLC_EXECUTABLE=` to it. **Verify the runtime banner says
434-
`matrix cores: NV_coopmat2` before trusting any number.** llama.cpp at pin
435-
`237ad9b96` is unpacked at `~/lcpp-vk` with `build-vk/bin/llama-bench` built.
434+
`matrix cores: NV_coopmat2` before trusting any number.** llama.cpp is
435+
unpacked at `~/lcpp-vk` with `build-vk/bin/llama-bench` built, **and that tree
436+
is the SUPERSEDED fork `237ad9b96`, not the pin.** Do not reuse it. The
437+
llama.cpp oracle is stock `b10451` since 2026-08-16
438+
([`oracles/llama-cpp.md`](oracles/llama-cpp.md)). `237ad9b96` is a local-only
439+
commit on the developer's `localai-paged` branch, 65 of our own performance
440+
commits past upstream `b9827`, built from a working tree with 27 uncommitted
441+
entries. `~/lcpp-vk` therefore reproduces neither the pin nor any identifiable
442+
object. The `BENCH-VK-LLAMA` decode `4.36 vs 4.35 MET` measured with it is the
443+
**most fragile verdict** in the enumeration, a 0.23% margin inside a 0.69%
444+
spread, and re-taking it is owed under
445+
[#1003](https://github.com/mudler/vllm.cpp/issues/1003). Unpack the pinned SHA
446+
fresh and assert `git status --porcelain` empty before recording any number.
447+
Enumeration and the clean-tree rule:
448+
[`specs/oracle-llamacpp-repin-stock.md`](specs/oracle-llamacpp-repin-stock.md).
436449

437450
- **No Intel GPU exists on any box here**, so `BACKEND-XPU` end-to-end work is
438451
HW-BLOCKED; only policy-port, compile coverage and oneAPI CPU-device unit

.agents/feature-matrix.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ and reference-engine performance.
173173
| ID | Block | State | Grounded summary | Detailed evidence / spike |
174174
|---|---|---|---|---|
175175
| `QUANT-CUDA-GATES` | NVFP4 W4A16, NVFP4 W4A4, gate-specific FP8 W8A8 | `DONE` | support/correctness stays closed; performance remains `ACTIVE` at the current binding `9ecd9d0` **114/124**. FP4 tactics match, and clean `f344dec` closes W1D2/G2 with 27B **235/235** in default+rollback arms plus 35B/GGUF inertness. Component evidence remains open; no quantization speed credit follows | quant matrix §2 + [coverage spike](specs/quantization-coverage.md) |
176-
| `QUANT-GGUF` | llama.cpp encodings and output presets | `PARTIAL` | F32/Q4_0/Q8_0/Q3_K/Q4_K/Q5_K/Q6_K materialize; F16 was corrected to reader-only; CPU threadpool/chunked dispatch is correctness-gated. **The B4 speed/RSS checkpoint is NO LONGER pending and this cell was two tracks stale:** direct compute-in-quant has been live since CIQ `G4`, and the 20-core Arm/i8mm arm reached llama.cpp parity or better on every axis (`BACKEND-GATE-CPU-LLAMACPP`). Still open: the four-core A76 arm on speed, and the **x86_64** arm, whose quant path is portable-tier only (CIQ `G5`, [#433](https://github.com/mudler/vllm.cpp/issues/433)) | quant matrix §1 |
176+
| `QUANT-GGUF` | llama.cpp encodings and output presets | `PARTIAL` | F32/Q4_0/Q8_0/Q3_K/Q4_K/Q5_K/Q6_K materialize; F16 was corrected to reader-only; CPU threadpool/chunked dispatch is correctness-gated. **The B4 speed/RSS checkpoint is NO LONGER pending and this cell was two tracks stale:** direct compute-in-quant has been live since CIQ `G4`, and the 20-core Arm/i8mm arm reached llama.cpp parity or better on every axis (`BACKEND-GATE-CPU-LLAMACPP`). **That denominator is SUPERSEDED:** it was `237ad9b96`, our own local-only fork, and the oracle repinned to stock `b10451` on 2026-08-16, so every one of those axes is owed a re-take ([#1003](https://github.com/mudler/vllm.cpp/issues/1003), [#857](https://github.com/mudler/vllm.cpp/issues/857)). Still open: the four-core A76 arm on speed, and the **x86_64** arm, whose quant path is portable-tier only (CIQ `G5`, [#433](https://github.com/mudler/vllm.cpp/issues/433)) | quant matrix §1 |
177177
| `QUANT-VLLM-BREADTH` | generic FP8/MX, AWQ/GPTQ, CT integer, vendor methods, KV | `PARTIAL` | gate-specific implementations exist; generic dispatch/modes remain inventoried | quant matrix §§2-3 |
178178
| `QUANT-MLX` | affine Q2-8, MXFP4/MXFP8/NVFP4, QQ, mixed recipes/imports | `INVENTORIED` | required for Apple backend; no MLX runtime yet | quant matrix §4 |
179179

@@ -217,7 +217,7 @@ is configured, exactly as upstream loads its draft model on demand.
217217

218218
| Feature | Upstream | Status | Notes | Spec |
219219
|---|---|---|---|---|
220-
| MTP (Qwen3.6 MTP heads, k=1) | `v1/worker/gpu/spec_decode/`, `models/qwen3_5_mtp.py` |**DONE (`SPEC-MTP`, 2026-07-26)** | k=1 MTP spec-decode is COMPLETE + gated on the 27B GDN hybrid: three-way token-exact at c1 (our-ON == vLLM `--speculative-config mtp` == our-OFF, acceptance 16/16), c1 above vLLM every-axis, c2-c8 on-par-or-above, mixed-batch concurrency bit-exact, server/CLI/C-ABI `--speculative-config`; spec-OFF byte-identical. c>1 token bar is the ratified near-tie+SPEED form (bf16-batch-nondeterminism). 35B `Qwen3_5MoeMTP` e2e (M-mtp-2) + DFlash tracked separately | [specs/mtp-spec-decode.md](specs/mtp-spec-decode.md) |
220+
| MTP (Qwen3.6 MTP heads, any k) | `v1/worker/gpu/spec_decode/`, `models/qwen3_5_mtp.py` |**DONE (`SPEC-MTP`, 2026-07-26)**; DEPTH BUILT + CPU-gated (`SPEC-MTP-K-GT-1`, 2026-08-16, #81) | DEPTH: `num_speculative_tokens` > 1 is SERVED rather than silently clamped, k=1..4 through the production loader with the greedy tokens unmoved at every depth. The GPU half is OWED, so no speed number is claimed above k=1 and the default stays k=1. Acceptance at depth is unexercised on CPU. k=1 MTP spec-decode is COMPLETE + gated on the 27B GDN hybrid: three-way token-exact at c1 (our-ON == vLLM `--speculative-config mtp` == our-OFF, acceptance 16/16), c1 above vLLM every-axis, c2-c8 on-par-or-above, mixed-batch concurrency bit-exact, server/CLI/C-ABI `--speculative-config`; spec-OFF byte-identical. c>1 token bar is the ratified near-tie+SPEED form (bf16-batch-nondeterminism). 35B `Qwen3_5MoeMTP` e2e (M-mtp-2) + DFlash tracked separately | [specs/mtp-spec-decode.md](specs/mtp-spec-decode.md) |
221221
| Rejection sampler | `v1/worker/gpu/spec_decode/rejection_sampler.py` | ✅ landed (`SPEC-REJECTION` ACTIVE, I3) | greedy accept rule + per-request logits expansion, CUDA==CPU bit-exact; consumed by MTP DONE | [specs/mtp-spec-decode.md](specs/mtp-spec-decode.md) (2.4) |
222222
| GDN spec segments (metadata + slot-snapshot rollback) | `v1/attention/backends/gdn_attn.py`, `fla/ops/fused_sigmoid_gating.py` | ✅ landed (`SPEC-GDN-SEGMENTS` ACTIVE, I4/I5a/I7) | metadata split + reclassification, `T>1`/IS_SPEC recurrence, conv rollback, k+1 slots, mixed split/merge; bit-exact; consumed by MTP DONE | [specs/mtp-spec-decode.md](specs/mtp-spec-decode.md) (3) |
223223
| DFlash (block-diffusion drafter) | in-pin + published drafts for our models | 🚧 **spec written** (after MTP) | DGX-Spark community container exists; GDN slot memory at k=15 flagged | [specs/dflash-spec-decode.md](specs/dflash-spec-decode.md) |
@@ -283,7 +283,7 @@ evidence.
283283
|---|---|---|---|---|
284284
| `BACKEND-CUDA-SM121` | GB10/sm121a | `PARTIAL` | gate workload built, traced, token/perf gated; full component-family coverage is open | [backend row](backend-matrix.md#cuda-target-rows) |
285285
| `BACKEND-CUDA-OTHER` | vLLM sm70/75/80/86/87/89/90/100/101/103/110/120 targets | `ACTIVE` | 9 CUDA arches build-supported (sm80/86/87/89/90a/100a/103a/110/120a, single-arch portable-kernels-only, `-Werror` clean, SASS emitted); sm70/75/101 not build-supported; no non-121a target is runtime-validated | [backend matrix](backend-matrix.md), [CUDA inventory](specs/cuda-architecture-inventory.md) |
286-
| `BACKEND-CPU` | production CPU | `PARTIAL` | shared CPU path is correctness-gated and the 20-core Arm/i8mm Qwen3.5-2B single-stream llama.cpp floor is closed; server concurrency is open. Raspberry Pi 5 Cortex-A76 R4-R5 is green: QEMU-built artifact, exact output, and an AAPCS64 Q8 leaf that beats compiler SDOT 3.66-5.08% on M1/T1 and M128. Its separate same-file llama.cpp floor is now measured/NOT MET on speed: vllm.cpp is 0.461x prefill and 0.653x decode/E2E, while using 24.2% less RSS; exact-prompt 64-token output matches. M1/T4 is −2.43%; BF16 GEMM, speed closure and concurrency remain open | [backend matrix](backend-matrix.md), [A76 Q8 dot](specs/cpu-a76-q8-dot.md), [assembly evidence](../docs/bench-evidence/rpi5-a76-q8-dot-20260806.md), [llama.cpp evidence](../docs/bench-evidence/rpi5-a76-llamacpp-20260806.md) |
286+
| `BACKEND-CPU` | production CPU | `PARTIAL` | shared CPU path is correctness-gated and the 20-core Arm/i8mm Qwen3.5-2B single-stream llama.cpp floor is closed **against a SUPERSEDED denominator**. It was our own local-only fork `237ad9b96`, the oracle repinned to stock `b10451` on 2026-08-16, and both the closing prefill `1.18x` and the `1.01x`/`0.97x` ties are owed a re-take ([#1003](https://github.com/mudler/vllm.cpp/issues/1003)); server concurrency is open. Raspberry Pi 5 Cortex-A76 R4-R5 is green: QEMU-built artifact, exact output, and an AAPCS64 Q8 leaf that beats compiler SDOT 3.66-5.08% on M1/T1 and M128. Its separate same-file llama.cpp floor is now measured/NOT MET on speed: vllm.cpp is 0.461x prefill and 0.653x decode/E2E, while using 24.2% less RSS; exact-prompt 64-token output matches. That arm ran stock `b9892`, a third revision that is neither pin, so its RSS win is owed a re-take too (#1003). M1/T4 is −2.43%; BF16 GEMM, speed closure and concurrency remain open | [backend matrix](backend-matrix.md), [A76 Q8 dot](specs/cpu-a76-q8-dot.md), [assembly evidence](../docs/bench-evidence/rpi5-a76-q8-dot-20260806.md), [llama.cpp evidence](../docs/bench-evidence/rpi5-a76-llamacpp-20260806.md) |
287287
| `BACKEND-ROCM` | ROCm | `INVENTORIED` | source/dispatch spike required; no "one flag" support claim | [backend matrix](backend-matrix.md) |
288288
| `BACKEND-MLX` | Apple Metal through MLX | `ACTIVE` | Metal/MLX skeleton ACTIVE: two models (OPT-125m, Qwen3-0.6B) run e2e + pass correctness, native-MSL GEMM, batched command buffers 1.50x (compute-bound at 98%+); optional MLX GEMM provider | [backend matrix](backend-matrix.md) |
289289
| `BACKEND-VULKAN` | Vulkan | `ACTIVE` | **22 NATIVE kernels**; **opt-125m RUNS END TO END, STRICT token-exact 6/6 prompts / 96/96 tokens vs the vLLM 0.25.0 oracle, 0 provider declines** of the CPU backend's 87 registered ops (GEMM both orientations, embedding, greedy argmax, block-paged attention + KV write, QKV split, rotary apply, elementwise/norm/fusion, and the GDN/conv1d glue: sigmoid gate, gated RMSNorm, state gather/scatter, decode conv1d update, fused post-conv); the other 65 served by the portable reference tier (CPU kernel, unified memory). `kGdnPrefill`/`kGdnDecode`/`kCausalConv1dFwd` deliberately still host-tier; `kRopeCosSinCache` stays host by design (double-precision table, mirrors vLLM). No speed number owed | [backend matrix](backend-matrix.md), [campaign spec](specs/vulkan-full-support.md) |

0 commit comments

Comments
 (0)