You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The pain comes from having multiple long-lived branches, not from how the source is laid out. Move to a single branch with per-major directories and most of it goes away. Build-time macros (proposal #2) is a nicer end-state but the wrong first step.
What I found
The .pyx.in/.pxd.in files are not hand-written templates. They're generated, with a banner: "automatically generated… Do not modify it directly."
What differs between main (13.x) and 12.9.x is real CUDA 12-vs-13 API surface (new enums, structs, renumbered values) — emitted by the generator. ~600 lines in cydriver.pxd.in alone.
All generated output (56 .pyx/.pxd/.cpp + 18 .in) is git-tracked. The build already regenerates from the installed toolkit's headers, so the committed copies are effectively cached.
So: every pain you listed (#965, #1058, #809, #1120) exists because there are multiple branches. Collapse to one branch and all four go away — independent of dirs-vs-macros.
The two proposals
#1 — per-major directories on main (recommended first step)
One branch. Each CUDA major is a generated directory: gen/v12/, gen/v13/. New major = copy + regenerate. EOL = delete the directory. No branch is ever cut or retired.
Hand-written code (__init__.py, _lib/, build_hooks.py, ci/, .github/, docs) lives once. A fix is one PR — no backport.
Build/release picks the major from the toolkit headers (already keys off CUDA_PATH) and maps gen/vNN/ onto the cuda.bindings package. Same package name, major-distinct versions, one installed at a time — no wheel collisions.
#2 — single source + build-time macros (better end-state, later)
The deltas are real API differences the generator owns. A single tree with {{if cuda_major==13}} means either hand-editing thousands of generated symbols, or teaching the upstream generator to emit version-gated code. That's a generator project, not a repo change. (CuPy does this — worth a look once/if the generator supports it.)
Migration path
Make the build's major-selection explicit so a gen/vNN/ dir can be picked deterministically.
Move 13.x into gen/v13/; verify wheels are byte-equivalent to today.
Activity
rparolin commentedon Jun 9, 2026
TL;DR
The pain comes from having multiple long-lived branches, not from how the source is laid out. Move to a single branch with per-major directories and most of it goes away. Build-time macros (proposal #2) is a nicer end-state but the wrong first step.
What I found
.pyx.in/.pxd.infiles are not hand-written templates. They're generated, with a banner: "automatically generated… Do not modify it directly."main(13.x) and12.9.xis real CUDA 12-vs-13 API surface (new enums, structs, renumbered values) — emitted by the generator. ~600 lines incydriver.pxd.inalone..pyx/.pxd/.cpp+ 18.in) is git-tracked. The build already regenerates from the installed toolkit's headers, so the committed copies are effectively cached.So: every pain you listed (#965, #1058, #809, #1120) exists because there are multiple branches. Collapse to one branch and all four go away — independent of dirs-vs-macros.
The two proposals
#1 — per-major directories on
main(recommended first step)gen/v12/,gen/v13/. New major = copy + regenerate. EOL = delete the directory. No branch is ever cut or retired.__init__.py,_lib/,build_hooks.py,ci/,.github/, docs) lives once. A fix is one PR — no backport.CUDA_PATH) and mapsgen/vNN/onto thecuda.bindingspackage. Same package name, major-distinct versions, one installed at a time — no wheel collisions.#2 — single source + build-time macros (better end-state, later)
The deltas are real API differences the generator owns. A single tree with
{{if cuda_major==13}}means either hand-editing thousands of generated symbols, or teaching the upstream generator to emit version-gated code. That's a generator project, not a repo change. (CuPy does this — worth a look once/if the generator supports it.)Migration path
gen/vNN/dir can be picked deterministically.13.xintogen/v13/; verify wheels are byte-equivalent to today.12.9.xintogen/v12/and cut a patch release frommain— proves release works without a branch (closes the BUG:./ci/tools/download-wheelsdoes not exist in the backport branch #1120 class).gen/vs. regenerate in CI. If regenerating, validate generator availability in CI.11.8.x/12.2.x/12.9.xas their lines move to directories or hit EOL.Bottom line: single-branch is the decision that matters. Start with per-major directories; treat build-time macros as a later optimization.