agentsclimarketplace

Inference kernel whitebox debug

Skill cfregly/gpu-perf-tune/plugins/profile-and-optimize/skills/inference-kernel-whitebox-debug

31 GPU inference profiling and optimization skills for Claude Code, with a bundled MCP server

Install
npx -y skills add cfregly/gpu-perf-tune --skill inference-kernel-whitebox-debug

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

White-box debug a custom CUDA/CUTLASS kernel producing a WRONG numeric result (over-amplification, NaN, coherence) after black-box bisection is EXHAUSTED: every external lever varied (grid, pipeline depth, layout, dtype), the result deterministic + lever-independent, yet the structure reads correct. Two tracks: (A) an in-kernel operand + accumulator trace (`if constexpr`-gated to survive megakernel pipelining), (B) a standalone reproducer .cu instantiating the EXACT kernel template + TMA descriptors with controlled inputs (all-ones then real-dump) vs a host GEMM. Localizes the defect to operand-load vs MMA vs epilogue vs descriptor. Escalation tier above `inference-kernel-ncu-profile` when H/P are fine but the output is numerically wrong. Triggers on "white-box kernel", "kernel over-amplifies / NaN", "standalone reproducer", "in-kernel trace", "operand dump", "cutlass UMMA bug", or any combination of "white-box / reproducer / in-kernel / operand-trace" with "kernel / cutlass / UMMA / megakernel / vllm".

SKILL.md

11.2 KB, ~2.7k tokens by cl100k_base, as published. Nobody here has run it

inference-kernel-whitebox-debug

Purpose

Localize a NUMERIC defect inside a custom CUDA/CUTLASS kernel (not a thin error -- a real wrong result) to a specific internal stage: operand-load / MMA-accumulate / epilogue / descriptor. This is the deepest tier of the rigor ladder, above inference-kernel-ncu-profile (proves H + P -- tensor-core engagement + %SoL) and the "Read the source" rule (reads the kernel statically). White-box engineering goes further: it instruments or re-runs the kernel's INTERNAL data path with controlled inputs. (The same isolated single-op harness pattern -- call the production library op directly, TP=1, no engine-side imports, synthetic fixed-shape inputs -- is also the canonical L4 ncu path when in-engine app-replay is non-deterministic on a TP=N MoE+sparse model. See the ncu capture-hygiene section of the ncu-profile skill.) It is a standing, first-class option -- reach for it whenever a K3-K4 kernel is numerically wrong and the mechanism is invisible from outside. It is not a last resort. Canon: docs/METHODOLOGY.md.

When to use

Escalate here when ALL of:

  • the kernel produces a WRONG numeric output (over-amplification, NaN, a coherence / magnitude failure), AND
  • black-box bisection is exhausted -- you varied every external lever (grid, NUM_AB_STAGE/pipeline depth, layout/shuffle, dtype, the calling config) and the wrong output is deterministic and lever-independent, AND
  • the structural read of the kernel (the cute setup, the MMA loop, the epilogue) looks correct yet the output is still wrong.

Do NOT use it as a first move (cheaper: black-box A/B, the structural read, ncu for H/P). Use it precisely when those are spent and the bug is invisible from outside.

Recipe A -- in-kernel single-tile / operand numerical trace

Instrument the kernel itself to dump the operands as the compute unit consumes them + the accumulator, then compare to a host/torch hand-compute on the SAME inputs.

  1. Add a __device__ trace buffer + dump, gated if constexpr on the EXACT template instantiation under test. A compile-time gate (e.g. if constexpr (REDUCTION_SIZE == 6144)) compiles the probe ONLY into the instantiation you care about, survives aggressive megakernel cross-layer pipelining (a runtime flag set by another op races and dies), and touches no other kernel. Read the SMEM operands the MMA actually consumes (for an SS-UMMA, the smem tensors tCsA/tCsB, not the tCrA/tCrB descriptor iterators) with atomicMax(__float_as_int) for absmax, plus a one-shot printf of the first N values to see the layout. Dump the accumulator (tTR_rAcc) in the epilogue. Read back via the runtime's finalize hook (e.g. cudaMemcpyFromSymbol in persistent_kernel.py), rebuild/JIT, smoke.
  2. Control the three confounds (each manufactures a false "operand is over" reading):
    • batch/N padding -- when BATCH < MMA_N the TMA box is clamped, so the padding rows (N >= BATCH) are stale/zero and an all-elements absmax is confounded. Gate to real rows (N < BATCH) or print the values to see the real-vs-padding split.
    • layer/config -- an all-invocation absmax mixes layers. Late-layer massive-activation inputs are legitimately larger. Pin the layer or use a controlled input before calling the operand "over".
    • cross-op flags -- a runtime flag set by op X and read by op Y dies to pipelining, use the compile-time if constexpr keyed on the instantiation.
  3. Verdict logic: operands correct + accumulator ~Nx => the MMA/compute over-counts, operand ~Nx (after de-confounding) => operand-load/TMA bug. Accumulator correct => downstream (epilogue/store).

Recipe B -- standalone reproducer

Author a self-contained .cu that instantiates the EXACT kernel template + the EXACT TMA/descriptor types the production path uses, feeds CONTROLLED inputs, diffs vs a host GEMM. This removes ALL production-context confounds (interleave, pipeline, layer-varying input) and definitively localizes scale-vs-layout-vs-stride.

  1. Copy the instantiation + descriptors VERBATIM from the codegen site (e.g. task_register.cc's register_*_task code.e(...) block) -- the template params, the tma_2d<...> types (gmem/smem shape, strides, swizzle bits), the bias tensor. Do not re-derive them. Transcribe them.
  2. Controlled inputs, analytic check first. all-ones weight + input => a GEMM output MUST equal K everywhere. If the kernel gives ~Nx*K, the compute over-counts. Then feed the real dumped input + checkpoint weight and diff vs a host GEMM (relL2, kernel/ref_ratio).
  3. Build with the SAME flags the production JIT uses -- read them off a real compile line (the JIT log): include paths (-I<tree>/include -I<tree>/include/<pkg> -I.../deps/ cutlass/include ...), arch (-gencode=arch=compute_103a,code=sm_103a for GB300), -std=c++20, the project -D defines. Produce an EXECUTABLE (drop -shared / nvshmem-runtime. The task impl is self-contained), launch one CTA (the m_tile loop covers all output tiles), set the dynamic smem cudaFuncSetAttribute above sizeof(SharedStorage).
  4. Runtime-hang caveat (heavier build). A structurally-valid harness can still HANG (100% GPU spin) because the bare 1-CTA launch does not perfectly reproduce the production smem/barrier/scheduler context (a TMA-descriptor or named-barrier deadlock). Resolve with cuda-gdb on the spin (thread apply all bt). Commit the .cu + build script regardless -- they are reusable once the context is reproduced.

Reconcile + verify

Reconcile Track A + Track B -> name the exact stage/line -> apply the minimal fix -> verify against the reference trajectory (the golden numeric the kernel must match). A white-box localization is a VERDICT only when a controlled-input reproducer (or an unconfounded in-kernel trace) isolates it. A padding/layer-confounded absmax is a DRAFT -- walk it back per DRAFT-vs-VERDICT (that confound is exactly how an over-confident "the input is Nx" / "the router is also over" claim sneaks in).

Cross-skill join

QuestionToolSkill
What kernels run + sample-share?zymtracezymtrace-anchored-query
Absolute per-kernel duration / cuda-graph timelinensysinference-kernel-profile
Per-kernel occupancy / regs / smem / DRAM-BW / roofline (H + P)ncuinference-kernel-ncu-profile
Task-graph wiring (declared-but-unconsumed tensor)task-graph auditmirage-graph-coverage
Why is the kernel's NUMERIC OUTPUT wrong (operand vs MMA vs epilogue)in-kernel trace + standalone reproducerthis skill

Run ncu first to confirm H/P are fine (tensor cores engaged, near-ceiling) -- if H/P are the problem it is a K/R/H/P/A mismatch, not a numeric bug. This skill is the escalation when H/P are fine but the output is numerically wrong.

Scaffolding (MCP)

perf_tune_report_kernel_reproducer_scaffold generates the Track-B .cu + build script from a kernel signature (header, kernel name, template params, input source), so the boilerplate (includes, instantiation, controlled inputs, host-GEMM diff, the GB300 build flags) is not hand-retyped each time. Hand-edit the generated descriptors to match the codegen site exactly.

Next lever / BREAKTHROUGH (Grind Mandate)

If this skill emits a measured result, its output MUST end by naming the next perf lever, its expected unlock (direction + rough magnitude), and the gate that proves/refutes it, per docs/METHODOLOGY.md "Always be grinding". A measured win is the new floor, not the finish -- so do everything we can to find the next BREAKTHROUGH: the highest-EV unlock toward Speed-of-Light (a new champion / kernel / router / quant / parallelism / spec-decode win, or an unblocked stack), not just the next micro-lever. Rank the candidate breakthrough levers by value x cost (the GRIND FRONTIER, perftunereport value_view), pursue the top, bank the rest with evidence. Record WHY a refuted lever loses, update the standing frontier in the active bundle's HANDOFF.md. Never conclude "exhausted/optimal/done" without an explicit next-lever frontier (an empty frontier AND a documented SoL wall only). Delete this section ONLY if the skill produces no measurements.

Kernel rubric (K/R/H/P/A)

A white-box defect hunt is almost always on a K3-K4 op (dense GEMM / attention / NVFP4 MoE GEMM) at R1-R3 (library / CuTe DSL). Record (K,R,H,P,A) for the kernel under test in the bundle's SOURCE.md. White-box engineering is orthogonal to the H/P win-gate (that is inference-kernel-ncu-profile's job) -- it answers CORRECTNESS, not competitiveness: a kernel can be H4/P4 (tensor cores, near-ceiling) and still be numerically wrong, which is exactly when you escalate here.

Worked example: an apparent ~10x over-amplification refuted by the reproducer

A shared-expert gate_up GEMM (BF16, K=6144/OUTPUT=1024) appeared to over-amplify ~10x. Black-box bisection refuted ~13 mechanisms and the structural read was clean. Track A (an if constexpr (REDUCTION_SIZE==6144) operand trace of tCsA/tCsB + accumulator) confirmed the weights load correctly (absmax 1.30) and the real input rows load faithfully -- an all-layer input absmax of 11-15 was late-layer massive activations (the padding/layer confound, walked back) -- pointing at the MMA itself. Track B (a standalone reproducer with the exact instantiation + TMA descriptors, all-ones input, sm_103a build) first hit the runtime-hang friction. The hang was the BATCH=8 < MMA_N=16 clamped-box path. At BATCH=16 the reproducer ran clean and the GEMM was numerically correct (all-ones -> out==K=6144, ratio 1.000. Non-uniform -> relL2 0.00182 vs a host GEMM): the over-amplification was REFUTED. The "~10x" was the BATCH<MMA_N padding confound (stale smem rows read by an all-rows absmax) -- the exact DRAFT-vs-VERDICT lesson this skill encodes: a VERDICT needs the controlled-input reproducer, not an in-kernel absmax.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Gives 0 of the 12 instructions most debug triage skills give in ~2.7k tokens

Counted across 839 of the 1,149 authors here whose files we hold, read 2026-08-07

  • Investigate root cause before proposing any fixin 102 of 839, across 67 files
  • Read error messages completelyin 89 of 839, across 49 files
  • Create a failing test case before fixingin 84 of 839, across 46 files
  • Reproduce the issue consistentlyin 82 of 839, across 41 files
  • Change one variable at a timein 82 of 839, across 42 files
  • Check recent changesin 74 of 839, across 36 files
  • Write the regression test before fixingin 74 of 839, across 40 files
  • Fix the root cause not the symptomin 60 of 839, across 45 files
  • Implement a single fix at a timein 59 of 839, across 20 files
  • Trace data flow backward to the sourcein 50 of 839, across 20 files
  • Remove all debug instrumentationin 49 of 839, across 13 files
  • Form a single hypothesisin 48 of 839, across 18 files

Said here and by no other author read

  • gate in-kernel probes with compile-time constants
  • read shared memory operands the MMA consumes
  • control batch, layer, and cross-op flag confounds
  • copy template instantiations and descriptors verbatim
  • use controlled inputs and analytic checks first
  • build the reproducer with production flags

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 326,984. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.