Repository navigation
cuda: add a Turing (sm_75) path - #6
Conversation
Turing has no cp.async, no __reduce_max/min_sync and no m16n8k16 f16 or m16n8k16/k32 int8 mma, so the kernels do not compile there. The f16 GEMM becomes two m16n8k8 steps on the same accumulator (a0/a1 and a2/a3 are the two k-halves of the k16 A fragment, b0/b1 the two halves of B). cp.async copies through registers; a predicated-off cp.async zero-fills its bytes, and the prefill attention relies on that for rows past the last key, so the fallback writes zeros too. The two __reduce_*_sync in topk_warp are warp shuffles. There is no int8 GEMM on Turing either: gemmi/gemmis are not built and gemm_raw takes the f16 path. The new Backend::int8_gemm lets the kernel tests build the reference the backend actually uses (Vulkan keeps its old behavior). sm_75 has 64 KB of shared memory a block. attn_prefill at head_dim 256 uses a 16-key tile instead of 32, and attn_decode_gqa at head_dim 256 skips its cp.async KV prefetch. The dynamic shared memory opt-in now follows the device limit minus the kernel's statics instead of a fixed 96 KB.
|
First: Nice username, I like it, and ty for contribute What I ran on an RTX 3060 (sm_86), with this PR merged onto current main:
Two changes before merging:
One interaction for whichever lands second: #9 adds |
# Conflicts: # src/cuda/mod.rs # src/vulkan/mod.rs
* docs(parity): record V100 Vulkan parity baseline (M0-T7) 20 prompts x 32 greedy tokens against llama-server 0.9.0-dev build 12110 (cd959bae9) on the V100, parity mode with --fixed-experts. strict 625/640 = 97.66%, either llama.cpp mode 629/640 = 98.28%, llama.cpp self-agreement 630/640 = 98.44%: below the 634/640 either-mode bar, recorded as a documented deviation with a second parity-mode repeat (identical) and the default path (626/630). No new Xid. Artifact in docs/parity/vk-sm70.json. * docs: fix the 3060 comparison in the M0-T7 deviation note
I have a 2060 (sm_75) and tried to run Qwen3.6-35B-A3B on it. The CUDA backend doesn't get as far as loading the kernels there: NVRTC stops on cp.async, __reduce_max_sync/__reduce_min_sync and the m16n8k16/m16n8k32 shapes, all of which want sm_80.
This adds an sm_75 path. It's not the fastest thing on earth, but it runs:
Numbers on this box (RTX 2060 6 GB, Ryzen 5 7600X, 31 GB RAM, UD-Q2_K_XL, ctx 8192, ~2.6 GB of experts resident), one run:
With --kv q8 --ctx 131072 a full 128k prefill takes 4m40s (467 tok/s) and decoding at that depth sits around 32 tok/s.
Tests: cargo test --release with STRATA_MODEL pointing at that model. Everything that runs on CUDA passes: backend, cpu_moe, gguf, gpu_model 10/10, kernels 20/20, model, ops, quant, serve, tokenizer. kv_q8 and llama_numerics only fail on their Vulkan half here, because the only Vulkan device on this laptop is an AMD iGPU that reports no int8 and gives NaN/different results; I skipped Vulkan locally to check the CUDA side.
What I couldn't check: this is the only GPU I have, so the sm_80 paths are tested by compiling them, not by running them. The suite's split test runs both halves on the same card and passes, but that's not the same as two real GPUs.
If Turing isn't something the project wants to carry, feel free to close this.