Skip to content

docs: the three local-only follow-ups -- and a one-line CUDA defect they found - #501

Merged
bernardladenthin merged 1 commit into
mainfrom
claude/agent-report-b11538
Oct 10, 2026
Merged

bernardladenthin merged 1 commit into
mainfrom
claude/agent-report-b11538

Conversation

@bernardladenthin

Copy link
Copy Markdown
Owner

Follow-up to #500 (merged). One commit, documentation only, no source change.

Three things CI structurally cannot show, measured on the 5800H workstation at b11538. Two installs
were needed first: sccache 0.18.0 and the LunarG Vulkan SDK 1.4.363.0 — the latter only through an
elevated run, after two silent attempts failed with Cannot elevate access rights (a user-writable
--root and a reduced component set included). No reboot: the Vulkan runtime already ships with the
NVIDIA driver.

1. sccache with plain clang: the build is green and the cache is inert

build.bat probe sccache probe OK (wrapped cl.exe) — launcher is set
Build BUILD_EXIT=0, 745 steps
Compile requests / executed 720 / 1
Non-cacheable 719, hit rate 0.00 %

sccache prints the reason: Can't handle UnknownFlag arguments with -Xclang. It comes from
upstream llama.cpp, which sets -Xclang -fno-pch-timestamp unconditionally for Clang — so the
cl.exe jobs are unaffected and their measured hit rates stand. sccache can wrap plain clang
(proved in isolation), it just cannot cache this project's clang command lines. A Windows
CPU-variants CI job would build cold every time
, since it must use plain clang.

2. Part B — GPU inference

Backend pp512 tg128 vs CPU
cuda13 14 124 265.6 pp 28×, tg 4.3×
vulkan 10 127 243.7 pp 20×, tg 4.0×
cpu 503 61.3 —

Both offload 29/29 layers. Vulkan sees two devices and correctly takes the discrete NVIDIA — with
Vulkan0 the AMD iGPU and Vulkan1 the NVIDIA, the opposite assignment to the one CLAUDE.md
records from a run with CUDA loaded, which is exactly why its rule is "name the backend, never the
index". And Vulkan's first call after a cold shader cache measured pp512 25.9 against ~10 100 warm.

3. E1 — the GPU backend as a module beside the CPU set: works, with two blockers

One directory carries the 14 CPU modules and ggml-cuda.dll; the process maps
ggml-cpu-haswell.dll and ggml-cuda.dll at once, 29/29 layers on the GPU, verify-native-deps.py
clean. nvcc even accepts the plain-clang host compiler the variants path forces.

(a) The GPU module is built and never shipped — ggml-cuda.dll (50.3 MB) and
ggml-vulkan.dll (43.9 MB) stay in llama/build/bin/Release/; the copy list that also writes
jllama-files.txt knows only the CPU modules plus ggml/ggml-base/ggml-rpc.

(b) CUDA as a module loses two thirds of its token generation — tg 88.8 against 265.6
(−66.6 %), pp −19.8 %, range 81.9–94.5, so not noise. Vulkan loses nothing (+5.2 % tg), which
ruled out the module boundary and pointed at something CUDA-specific. It is GGML_CUDA_GRAPHS:
ON in the static configure, OFF in the variants one. ggml defaults it off; llama.cpp sets
two defaults before adding ggml (GGML_LLAMAFILE at :166, GGML_CUDA_GRAPHS at :170); our
variants path adds ggml itself and repeats only the first (llama/CMakeLists.txt:322). CUDA graphs
act per token, which is why generation collapses and prompt processing barely moves.

Proposal: repeat the second line too. Latent today (no job builds variants + CUDA) and worth a
general rule — every *_DEFAULT llama.cpp sets before its own add_subdirectory(ggml) must be
repeated in the variants path. CLAUDE.md's "the one ggml default … is repeated" is now wrong;
there are two.

The test plan gains what is now measured: the 5800H's module confirmed, the forced-backend and
cold-shader-cache traps, the module question with its two blockers, and a repeat trigger for this
class of defect.

🤖 Generated with Claude Code

https://claude.ai/code/session_01E2h8gXyyE5UeimkL9vQv9G

…hey found

sccache, GPU inference and the GPU-backend-as-a-module question, measured on
the 5800H workstation at b11538. Two installs were needed first: sccache 0.18.0
and the LunarG Vulkan SDK 1.4.363.0, the latter only through an elevated run
(two silent attempts failed with "Cannot elevate access rights", a
user-writable --root and a reduced component set included). No reboot; the
Vulkan runtime already ships with the NVIDIA driver. CUDA here is toolkit 13.3
against the pinned 13.4, and both GPU builds are single-arch sm_86 -- right for
a measurement, wrong for a release.

1. sccache with plain clang: the build is green and the cache is INERT. The
   probe passes (it compiles through sccache cl.exe) and the launcher is set,
   the build exits 0 -- and 719 of 720 compile requests are non-cacheable, hit
   rate 0.00 %. sccache prints the reason: "Can't handle UnknownFlag arguments
   with -Xclang". It comes from upstream llama.cpp, which sets
   -Xclang -fno-pch-timestamp unconditionally for Clang, so the cl.exe jobs are
   unaffected and their measured hit rates stand. sccache CAN wrap plain clang
   (proved in isolation, exit 0, cacheable) -- it just cannot cache this
   project's clang command lines. A Windows CPU-variants CI job would therefore
   build cold every time, since it must use plain clang.

2. Part B, GPU inference: cuda13 pp512 14124 / tg128 265.6 and vulkan 10127 /
   243.7 against the CPU's 503 / 61.3, both offloading 29/29 layers. Vulkan sees
   two devices and correctly takes the discrete NVIDIA -- with Vulkan0 the AMD
   iGPU and Vulkan1 the NVIDIA, the opposite assignment to the one CLAUDE.md
   records from a run with CUDA loaded, which is exactly why its rule is "name
   the backend, never the index". And Vulkan's first call after a cold shader
   cache measured pp512 25.9 against ~10100 warm.

3. E1, the GPU backend as a module beside the CPU set: it works. One directory
   carries the 14 CPU modules and ggml-cuda.dll, the process maps
   ggml-cpu-haswell.dll and ggml-cuda.dll at once, 29/29 layers on the GPU, 0
   dependency violations -- and nvcc accepts the plain-clang host compiler the
   variants path forces. Two defects stand in the way:

   (a) the GPU module is built and never shipped. ggml-cuda.dll (50.3 MB) and
       ggml-vulkan.dll (43.9 MB) stay in llama/build/bin/Release/; the copy list
       that also writes jllama-files.txt knows only the CPU modules plus ggml,
       ggml-base and ggml-rpc.

   (b) CUDA loses two thirds of its token generation as a module -- tg 88.8
       against 265.6 (-66.6 %), pp -19.8 %, sample range 81.9-94.5, so not
       noise. Vulkan loses nothing (+5.2 % tg), which ruled out the module
       boundary and pointed at something CUDA-specific. It is GGML_CUDA_GRAPHS,
       ON in the static configure and OFF in the variants one: ggml defaults it
       OFF, llama.cpp sets two defaults before adding ggml (GGML_LLAMAFILE at
       :166 and GGML_CUDA_GRAPHS at :170), and our variants path adds ggml
       itself and repeats only the first (llama/CMakeLists.txt:322). CUDA graphs
       act per token, which is why generation collapses and prompt processing
       barely moves. Proposal: repeat the second line too. Latent today (no job
       builds variants+CUDA) and the general rule is worth writing down -- every
       *_DEFAULT llama.cpp sets before its own add_subdirectory(ggml) must be
       repeated there. CLAUDE.md's "the one ggml default ... is repeated" is
       now wrong; there are two.

The test plan gains what is now measured: the 5800H's module confirmed, the
forced-backend and cold-shader-cache traps, the module question with its two
blockers, and a repeat trigger for the GGML_CUDA_GRAPHS class of defect.

No source file was edited.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2h8gXyyE5UeimkL9vQv9G
@sonarqubecloud

Copy link
Copy Markdown

This branch had an error being deployed

1 failed and 1 active deployments
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.

1 participant