Skip to main content

Hardware-free static analyzer for CUDA kernel binaries: source-attributed register pressure, spills, occupancy, diffs, and CI gates. No GPU required.

Project description

cuxray

PyPI CI License

Static analysis and optimization for CUDA kernel binaries — register pressure, spills, occupancy, bank conflicts — without a GPU.

cuxray reads the decisions the compiler froze into your cubin and combines them with NVIDIA's published architecture tables. Because those models are exact, it can go beyond reporting problems: it searches for fixes (shared- memory swizzles, register caps) and verifies them before suggesting them. Everything it reports is ground truth; anything unknowable is reported as unknowable, with the reason.

$ pip install cuxray
$ cuxray report kernel.cubin --threads 256

  moe_gemm(float const*, float*, int)
    regs 168 · smem 8 KB
    spills: 24 stores (96 B) / 24 loads (96 B)
  location         stores   loads   loop depth
  moe_gemm.cu:145  24       24      1 🔥
    peak pressure: 166 live GPRs at moe_gemm.cu:142
    occupancy @256 thr: 16.7% (1 blocks/SM) — limiter: registers
      cliff: registers → 128 (-40) gives 2 blocks/SM (33.3%)

Features

Analyze

  • Spill maps: every spill instruction is attributed to a source line and weighted by loop depth, instead of one aggregate byte count per kernel.
  • Occupancy with limiters and cliffs: blocks/SM, which resource binds, and the nearest boundary (e.g. "8 fewer registers gains a block per SM").
  • Bank-conflict and coalescing analysis computed from per-lane address tracking in the SASS, including XOR-swizzled and ldmatrix layouts.
  • Register-pressure curves from nvdisasm life ranges, mapped to source.

Optimize

  • cuxray solve searches CUTLASS-style swizzles and returns only layouts it has verified conflict-free for every shared access in the kernel.
  • cuxray tune-regs recompiles across -maxrregcount values and marks the Pareto-optimal occupancy/spill trade-offs.
  • Conflict reports include verified fix suggestions with their shared-memory cost and occupancy impact.

Integrate

  • CI gating with exit codes, per-kernel budget files, build-to-build diff with regression detection, SARIF output for PR annotations, and a reusable GitHub Action.
  • Stable, versioned JSON from every command; results cached on disk.
  • No setup: runs on any Linux machine, fetching pinned, sha256-verified NVIDIA binary utilities on first use. Works on binaries you didn't build — a vLLM wheel, a Triton cache, a .so from PyPI.

Usage

Inspect — resources, spills, pressure, occupancy, access patterns (--threads is inferred from .reqntid/__launch_bounds__ when present):

cuxray report kernels.so --kernel "moe.*" --threads 256
cuxray ls kernels.so                      # fast listing, no disassembly

Fix bank conflicts — derive a verified swizzle for the whole kernel:

$ cuxray solve kernel.cubin --threads 32
  solution: Swizzle<3,4,3>  (zero smem cost, verified on all accesses)
    apply to byte offsets: addr ^ ((addr >> 3) & 0x70)
    e.g. ldsm_async.cu:37 LDSM: 8-way → clean

Tune register caps — map the whole trade-off in seconds of CPU:

$ cuxray tune-regs kernel.ptx --threads 256
   cap   regs   spill bytes   blocks/SM   occupancy
    40     40           424           6      100.0%   ● pareto
    48     48             0           5       83.3%   ● pareto
  none     56             0           4       66.7%

Gate regressions in CI — exit 1 on violation, per-kernel budgets, SARIF annotations:

cuxray gate kernels.so "spill_instrs==0, regs<=168, bank_ways<=2" --threads 256
cuxray gate kernels.so --budget budgets.json --sarif out.sarif
cuxray diff old.so new.so --fail-on-regression
- uses: KookiesNKareem/cuxray@main
  with: { path: build/kernels.so, gate: "spill_instrs==0", threads: "256" }

What-if — no binary needed:

cuxray occupancy --arch sm_120 --regs 168 --threads 256 --sweep

Every command takes --json / -o (schema: cuxray schema). cuxray doctor shows toolchain and cache state.

Inputs

Input Handling
.cubin analyzed directly
host ELF (.so, .o, executable) embedded cubins extracted and analyzed
directory recursive *.cubin walk (Triton caches)
.ptx assembled with ptxas

Architectures: compute capability 7.5–12.x (Turing → Blackwell, including a-variants like sm_120a).

How it works

nvdisasm life ranges give per-instruction register liveness with source mapping; cuobjdump provides per-kernel resources from any cubin; a lane- value dataflow over the SASS recovers how each memory address varies across the 32 lanes of a warp; occupancy is a port of NVIDIA's cuda_occupancy.h. GPUs execute SASS in order with no register renaming, so the binary is a complete record of what the hardware will do — reading it is not simulation.

Validation

  • Occupancy: 4,344/4,344 configs match NVIDIA's cuda_occupancy.h across all supported architectures; 54/54 match the CUDA runtime on real hardware.
  • Spill bytes: byte-exact against ptxas -v across dtypes and architectures.
  • Bank verdicts: hardware-timed (flagged kernel 12× slower than its clean twin; swizzled and padded twins within 2%); solve re-derives the canonical CUTLASS Swizzle<3,4,3> for 128-byte fp16 tiles.
  • Robustness: ~161k production kernels (vLLM, PyTorch wheels) analyzed with zero crashes and zero false-positive conflict flags.

Limitations

  • Static facts only: cache behavior, achieved bandwidth, and data-dependent addressing need a profiler; cuxray reports those accesses as unanalyzable rather than guessing.
  • Block shape and dynamic shared memory are launch parameters — pass --threads / --smem-dynamic when the binary carries no metadata (cuxray warns when this matters).
  • Warp-specialized register reallocation (setmaxnreg) makes static occupancy pessimistic; detected and flagged.
  • Linux only. Compile with -lineinfo for source attribution.

Roadmap: scheduling/stall analysis from the compiler's embedded control bits.

License

Apache-2.0. Not affiliated with NVIDIA; CUDA binary utilities are downloaded from NVIDIA's redistributable archive under the CUDA Toolkit EULA.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cuxray-0.2.0.tar.gz (412.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cuxray-0.2.0-py3-none-any.whl (64.8 kB view details)

Uploaded Python 3

File details

Details for the file cuxray-0.2.0.tar.gz.

File metadata

  • Download URL: cuxray-0.2.0.tar.gz
  • Upload date:
  • Size: 412.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for cuxray-0.2.0.tar.gz
Algorithm Hash digest
SHA256 19d42e067435005a22102bcae222eb798668d539ddd0cb1beafffe982461f83e
MD5 9a6e1f579e06f7324bcec17e1eaa6cc2
BLAKE2b-256 332f3957b8db713c508df8e1617a1e77965577ebc106ea354ade496ab0b03672

See more details on using hashes here.

File details

Details for the file cuxray-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: cuxray-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 64.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for cuxray-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 879edb92efb3d7f7b63de126ca04c857aeb5ea5dbfe67c83bfdec87288ce483a
MD5 3313f26278db7dd0f088d5cee0aef704
BLAKE2b-256 7fa9f4e08d1120c0cdacac9bc8caf1ad5669185a41621876d3976d35e196b0aa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page