Skip to content

cuda.bindings: support multiple CTK release lines on main - #2737

Open
rwgk wants to merge 97 commits into
NVIDIA:mainfrom
rwgk:agent/cuda-bindings-12-on-main
Open

rwgk wants to merge 97 commits into
NVIDIA:mainfrom
rwgk:agent/cuda-bindings-12-on-main

Conversation

@rwgk

@rwgk rwgk commented Aug 31, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #1199. This continues Keith Kraus's original PR #2675, preserving his CUDA 12 source import and initial build, test, and release integration. The replacement became necessary when that PR's temporary base branch was deleted after #2467 merged.

Maintain both supported CUDA ABI-major source trees on main, with short release branches available for stabilization and urgent fixes. Release each bindings line independently, together with its matching cuda-python metapackage.

Package root Role Build/test toolkit
cuda_bindings_12/ Maintenance 12.9.1
cuda_bindings/ Current 13.4.2

The roots build the same cuda-bindings distribution and cuda.bindings namespace in separate environments. The CUDA 12 source import includes v12.9.9. The October 3 refresh merges main through ab9e20fd6a525d526d85d529571b3940824e8467 and incorporates the subsequent 12.9.x workflow dependency updates through 1635cf2c5552bc329497779b73d3ec72075e2434. After merge, 12.9.x is retained as historical release evidence.

Decisions Implemented

  1. Source layout and scope: keep cuda_bindings_12/ for CUDA 12 and cuda_bindings/ for CUDA 13. ci/versions.yml records their package paths, toolkit versions, and current/maintenance roles. Support exactly one current and one maintenance root with distinct CUDA majors. Naming the roots for a future major-version rollover remains a future decision.
  2. Release branches: integrate shared development on main; cut short stabilization branches from a tested commit when needed. Urgent fixes can start on the frozen branch, with a linked follow-up PR to reconcile the fix back into main. A new manual backport workflow accepts one merged PR and one existing non-default target branch, opens a reviewable PR, and leaves CI approval and merging to the normal process. The historical 12.9.x branch is not resumed.
  3. Major versus patch maintenance: major-line maintenance can include explicitly selected API, Python, or platform compatibility work. A frozen patch release admits its approved fixes and release prerequisites. The updated release checklist and new bindings release guide require recording that scope in the checklist and release notes.
  4. Independent releases: a bindings tag selects one bindings root and its metapackage, with published Pathfinder and no Core release. Ordinary development CI still tests dependent Core variants. A frozen tested branch provides a release source when unrelated development on main is unfinished; it does not waive required validation. — For details, see this comment below.
  5. SCM and packaging: Package versions continue to use standard setuptools-scm, with each bindings line selecting its own tag family. A temporary fallback handles CUDA 12 builds before an eligible tag is reachable. The standalone metapackage carries matching build metadata, and pre-commit/CI checks prevent those copies from drifting. See the SCM and packaging review guide below.
  6. Release configuration and notes: use the package layout and toolkit settings recorded in ci/versions.yml at the release tag. The new release tooling supports tags containing this configuration; older tags require compatible historical tooling. For normal releases, CI: Release requires each component's exact-version, nonempty notes in the tagged source, including separate metapackage notes. The existing exemption for .postN releases remains.
  7. Cross-root and generator review: authors and reviewers assess handwritten changes in both roots and explain any difference in applicability. Named SYNCED blocks identify deliberately identical snippets; agent instructions require checking every copy during development and review. The maintenance policy requires future generated imports to record the cybind revision, toolkit inputs, commands, and manual adjustments. File seals verify file contents but do not establish generation provenance. Continuous toolkit QA, broader cybind changes, and a uniform pre-commit check for SYNCED blocks remain separate work.
  8. Test scope: exercise release routing, artifact selection and completeness, strict release notes, metadata consistency, and reachable-tag versioning. Unsupported old layouts fail explicitly. The full CI-tool suite runs in PR CI. Redundant snapshot/static-agreement tests and tests for the removed historical compatibility paths are removed.

SCM and packaging review guide

Click to un/expand
Reviewer question Intended behavior Where to inspect
Which tags determine a package's version? Each root selects its minor family; setuptools-scm handles parsing and version progression. CUDA 12 excludes the old v12.9.0 baseline. CUDA 13 configuration, CUDA 12 configuration
What happens before an eligible CUDA 12 tag is reachable? CI uses the configured development fallback plus the commit identifier. Once any matching tag is reachable, the override stops, including on descendants of prerelease or postrelease tags. The decision function
Why repeat metadata in the metapackage? Its standalone source distribution lacks the registry and sibling package files, so it carries its own selectors and fallback. Metapackage setup
What prevents those values from diverging? A validator enforces the selector and fallback rules for current/maintenance roots, then checks agreement with the metapackage and maintenance Pixi metadata. Consistency validator

The bootstrap regression cases cover no eligible tag, the excluded old baseline, a matching tag and its descendants, and an unreachable tag.

The key review question is: Does the custom fallback reliably get out of the way once standard Git-derived versioning can work?


The durable operating procedure is RELEASE-bindings.md, with shared ownership and rollover guidance in ci/README.md. The contributor CI overview now uses a maintained conceptual Mermaid diagram.

Implementation and Review Guide

  • Imports CUDA 12 source, tests, examples, docs, packaging, and Pixi lockfile. The existing coredump lifetime fix remains an intentional handwritten overlay.
  • Routes dependency-aware CI, wheels, sdists, tests, docs, and releases through the selected root; uses in-tree PEP 517 backends for independent source builds.
  • Validates complete release artifact matrices, excludes test wheels, preserves release suffixes, and requires exact-tag/exact-SHA successful CI for publishing.
  • Keeps release source and workflow control revisions distinct. Configuration from the workflow revision cannot replace the release tag's configuration. Unsupported old layouts fail before a release draft is created.
  • Removes branch-sourced artifacts and the old automatic 12.9.x backport policy. Adds explicit manual automation for selected stabilization branches.

Refreshed six-layer review aid

Read the new review-only branch in the order below, or open all six commits and the complete diff.

Layer Review focus
1. CUDA 12 source and adaptations Keith's source import through v12.9.9, maintenance fixes and build hooks, shared pytest safeguards, and repository support. This includes intentional overlays.
2. Package configuration and SCM Registry, per-line version selectors and fallback rules, standalone metapackage metadata, Core bindings-floor checks, and regression coverage.
3. Selective CI planning Changed-path impact, package-root and Core ABI selection, planner tests, and the CI diagram.
4. Build, test, and documentation routing Wheels, sdists, GPU tests, Pixi, coverage, docs/previews, and the Windows Python 3.15 PyYAML fix.
5. Tagged releases and artifact validation Qualified release-tag refs, supported tagged configuration, exact-version notes, artifact identity/completeness, and the release checklist.
6. Maintenance and release branches Shared-main policy, stabilization branches, explicit manual backports and reconciliation, release/generation guides, and retirement of the automatic 12.9.x policy.

The branch starts at main commit ab9e20fd6a525d526d85d529571b3940824e8467. Its final commit has exactly the same Git tree (6e95a59f35e36ab401e97eab785ae8f8253fa2eb) as the tested #2737 head 6c3de41b319622453b1a8ca38f21166c79db1a3a. Git verification confirms six single-parent commits and all 302 changed paths assigned once.

These are reading layers: each shared file is assigned in full to one layer, and intermediate commits need not build independently. The final tree is identical, but the reconstructed history differs; validation and merge decisions belong to #2737. This replaces the earlier review aid #2960, which remains a historical snapshot.

Validation

Current implementation head: 6c3de41b319622453b1a8ca38f21166c79db1a3a.

  • Local CUDA 13.4 QA passed using the existing TestVenv: 1,615 Pathfinder tests, 636 bindings tests in each of normal and PTDS modes, 4,340 Core tests, and both packages' Cython tests. The workflow and validation-helper changes require no native package rebuild.
  • CI-tool and Core bindings-floor suites: 268 passed, 55 subtests passed, using a source-built pure-Python PyYAML wheel with the compiler deliberately unavailable.
  • Release-ref rehearsal: six checks passed using the pinned checkout implementation with a real same-named branch and tag. Qualified release checkouts select the tag; missing tags fail; ordinary docs branch/default-ref behavior remains intact.
  • SCM metadata regression cases reject coordinated selector drift in both roots and a fallback on the current root. All three cases failed before the guard changes and pass afterward.
  • Full pre-commit: all checks passed except the three expected pre-merge canonical main/cuda_bindings_12 URL failures. Hosted pre-commit on both platforms is green.
  • Current-head CI is green at 6c3de41b319622453b1a8ca38f21166c79db1a3a (attempt 2). Pixi source-build/docs and lockfile freshness checks, Bandit, and the security suite are also green. In attempt 1, the Linux Python 3.14t / CUDA 12.9.1 / T4 job timed out after 90 minutes in a CuPy interop test; the attempt was then cancelled while two Windows L4 jobs were still queued, allowing a retry of the unfinished jobs. All three passed on the unchanged commit. The Linux retry reports 4,390 passing Core tests, with the previously stalled test passing in parallel in 21.6 seconds. The initial timeout's cause remains undiagnosed.
  • The formerly failing Windows Python 3.15 / CUDA 13.4.2 / L4 MCDM job now passes. Its log confirms PyYAML built as pyyaml-6.0.3-py3-none-any.whl, followed by 4,092 passing Core tests. All four Windows Python 3.15/3.15t native builds also pass. All Python 3.15 checks are included in this reported validation.

Earlier CUDA 12.9 local validation passed 390 maintenance bindings tests in each mode and its Cython tests. Follow-up cuFile isolation fixes restore global parameters and serialize the CUDA 12 module's process-global driver lifecycle; its parallel-run regression check passed 63 cases. These maintenance-runtime results precede the current workflow and metadata-validation fixes.

Earlier release rehearsals and their limits

The September 29 CUDA 12 package-source rehearsal passed all 48 build, sdist, GPU-test, documentation, and prerequisite jobs at source b00b677be366fd3638c78e26b99aa5b238602646. The original run failed its final custom harness assertion. Its validation follow-up passed, checking production wheel validation, package metadata, artifact provenance, and exact-source archive identity after correcting a harness expectation. The synthetic tag stayed local, with publication and docs deployment disabled. These results describe an earlier source revision.

Four earlier dry runs exercised retained real-tag artifacts: 13.4.3 bindings, 13.4.3 metapackage, 12.9.9 bindings, and 12.9.9 metapackage. They used the compatibility code subsequently removed from this PR. They are historical development evidence; the current tooling deliberately rejects these pre-registry tags.

Production release validation still requires a supported immutable tag and successful exact-tag/exact-SHA CI. Branch CI and synthetic rehearsals do not authorize publication.

Remaining Boundaries

The stale generated-file seal inherited from #2911 was corrected in 548b2615, with trailing blank-line normalization documented. This does not establish a fresh cybind regeneration.

Inherited documentation boundaries remain: two NVRTC generated-doc entries reference functions absent from the maintenance module, and README links retain the published 12.9.7 documentation. Archive digest companions retain their existing raw-digest format. After merge, recheck the three new canonical main/cuda_bindings_12 links that are unavailable before the directory reaches main.

Additional simultaneous public roots, unreleased-toolkit qualification, source-tree deduplication, and private QA reorganization remain outside this change.

Merge Status

The refreshed six-layer review aid matches the tested implementation head. The Fable 5 re-review confirms all three follow-up fixes and reports no new findings; its listed minor items remain follow-up work. The existing changes-requested review remains for renewed reviewer consideration. Production tags and publication require the normal separate release approval.

Author-side review disposition map (45 initially open threads)
Review area Final disposition Threads
Packaged helpers and named interfaces CI helpers are an installed package with shared parsing. Purpose-specific environment output and named build/test values replace redundant resolver/interface layers and positional arrays. 3916239618, 3916306849, 3916830273, 3917119898, 3931004805, 3931004808, 4031120234
Package identity, metadata and versions Keep two distinct major roots and explicit current/maintenance roles. Align registry, minor-family SCM selectors, metapackage and fallback metadata in pre-commit/PR CI; retain standard SCM parsing and progression, required major selection, and canonical release-tag spelling. 3916702314, 3916714594, 3917025344, 3917103010, 3931004811, 4031083254, 4031089226, 4031114469, 4031119779, 4062051063, 4062130293, 4062428956
Per-root CI and toolkit pins Build/test decisions follow the selected source root and Core ABI variant; tag routing checks ref_type, sdist matrices use the nonempty registry, and Pixi checks include both roots. Normal bindings development still builds both dependent Core variants. 3916813446, 3917038211, 3917048863, 3917080542, 3972240690
Release provenance and artifacts Resolve package metadata from ci/versions.yml in the tagged source. Reject pre-registry layouts; identify artifacts by exact tag and SHA, validate the complete wheel matrix, exclude test wheels, and require explicit dependency sources. Historical compatibility was removed in the October 4 design simplification. 3916893027, 3917053836, 3917070013, 3917097612, 3972240696, 3972240701, 3972240709, 3990562921
Release and maintenance guidance Document shared-main development plus independent release stabilization, explicit backport dispatch and main return paths. Replace the obsolete diagram and transient review narrative, pin CUDA 12 installation examples, and preserve development suffixes in docs paths. 3917111123, 3972240718, 3972240724, 4030956358, 4030959650, 4031036494
Cross-root changes and generation Remove the broad equality checker. Require per-root applicability review and target-specific generation provenance; semantic equivalence is not generally decidable. Retain distinct ignore lists while generation layouts differ. 3917089956, 4030963901, 4031135974, 4063090459
Regression fixes and cleanup Port CUDA 12 NVML visibility/platform handling, make temporary Git repositories independent of signing configuration, and remove the temporary link-check ignore file. 3972240732, 3972240736, 3972240741

These dispositions describe the implementation and retained design choices. They do not represent reviewer approval.

@rwgk rwgk added this to the cuda.bindings 13.5.0 & 12.9.10 milestone Aug 31, 2026
@rwgk rwgk added enhancement Any code-related improvements CI/CD CI/CD infrastructure cuda.bindings Everything related to the cuda.bindings module labels Aug 31, 2026
@rwgk rwgk self-assigned this Aug 31, 2026

rwgk commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 17e19e2

@rwgk
rwgk marked this pull request as ready for review September 29, 2026 16:08
@rwgk

rwgk commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

Work Report — GPT-6-Astra ultra — Autonomous drive to merge readiness

Outcome

The engineering work is complete, and I am comfortable with merging this implementation after the required renewed reviewer approval. PR #2737 is marked ready for review at 17e19e25b6b20eee6a5c13c8b39befd1b2b11a38. Three product commits are pushed, final normal CI is green with 108 successful jobs, release validation is complete, and all 52 discussion threads are resolved. The existing changes-requested review remains intact; the PR has not been merged.

The chosen direction is implemented: maintain the two supported CUDA ABI-major source roots together on main, and use short release branches when a version needs stabilization or an urgent repair. The implementation preserves independent bindings/metapackage releases for each line and documents how fixes return to integration.

Expand for details

Date: September 29, 2026. Requested report start label: 0640 America/Los_Angeles.
Final verification completed at 16:13 UTC / 09:13 America/Los_Angeles.

Starting point and scope

  • Initial PR head: 59ff7bd88756bda02164daefb0a71daff47b1d2e.
  • Initial main: 36e4d40a664f08ca88b30a50c3553da56d4ef3c2.
  • Historical 12.9.x and v12.9.9: 89713a7c8bf61037f6a0375ab611778c21f6f9cd; the live branch still matched this pin during the audit.
  • Audited all 52 inline review threads, including 45 initially unresolved threads, and the substantive review summaries.
  • Preserved Keith Kraus's original source-import and build/release integration credit from PR cuda.bindings: build 12.9 and 13.x selectively from main #2675.
  • Used GitHub App MCP for PR/review/job reads and GitHub CLI where branch, dispatch, pagination, or artifact operations needed it. Local Git and source inspection supplied exact revision evidence.

Added product commits

  1. e785620d9bb67c31f405cf54a609101f184d1714 - release-branch policy, manual backport workflow, reviewer decisions in durable documentation, contributor CI overview, missing support anchor, and removal of the temporary link exclusions.
  2. b00b677be366fd3638c78e26b99aa5b238602646 - metadata consistency, full CI-tool PR gate, standard SCM progression after reachable tags, historical release-note compatibility, and focused regression coverage.
  3. 17e19e25b6b20eee6a5c13c8b39befd1b2b11a38 - two explicit MyST targets, one repaired historical-note link, and an intentional release-note template marked orphan. Only four authored documentation files differ from the implementation/release-rehearsal candidate.

The user explicitly approved retaining the existing fork head as an exception to the standing upstream-branch convention, so all product commits were pushed to rwgk/cuda-python:agent/cuda-bindings-12-on-main. Its existing tracking configuration was preserved. Commits were added; existing history was not amended. No merge or production release was performed.

Decisions resolved

Branches and maintenance scope

main integrates both supported majors. A short release branch can freeze selected changes while development continues, and an emergency can start from a previously released modern-layout tag. Before the first migrated CUDA 12 release, the baseline must be a validated commit containing both roots; the historical single-root branch is not silently resumed.

Major-line maintenance can include explicitly selected API, Python, or platform support. Once a patch release is frozen, only approved fixes and release prerequisites enter that release. The checklist records this scope rather than treating the word "maintenance" as a complete release policy.

The manual backport workflow validates a merged source PR and one existing non-default target branch. The pinned action creates a reviewable PR. Label-derived targets are disabled; there is no automatic merge. Workflow-file changes need appropriate manual credentials, and generated changes need target-specific regeneration. Branch-first emergency repairs require a linked return to main and an applicability decision for both roots.

Durable procedure: RELEASE-bindings.md.

Layout, registry, and package boundaries

Keep the explicit CUDA 12 physical root and separate lifecycle roles. The supported shape is exactly one current and one maintenance major. Retaining the mapping avoids scattering source paths through workflows; it does not implement arbitrary numbers of supported public lines. A future 13/14 rollover must preserve the CUDA 13 source in a separate root before introducing CUDA 14.

Keep explicit minor-family SCM selectors so source builds do not accidentally select a prior minor's tags. Keep the standard setuptools-scm parser. The standalone metapackage's small selector/dependency policy is intentional because its sdist cannot import sibling source trees or repository CI metadata. The new guard checks the duplicated selectors and maintenance fallback against the actual package metadata.

Release independence and historical compatibility

Normal development CI includes affected dependents and can build both Core ABI variants. A bindings release tag selects one bindings root and its matching metapackage, uses published Pathfinder, and does not require another-major or Core release. Stabilization branches isolate unfinished development by freezing a tested source baseline; they do not waive required checks.

The tagged registry is authoritative when present. Historical trees without it retain a bounded compatibility path, with separate source and workflow-control revisions. Expired artifacts and indefinitely retired configurations are not promised to remain releasable.

Cross-root review and cybind

Handwritten changes require explicit applicability review in both roots. Semantic equivalence cannot generally be established by comparing bytes. Generated imports should record the generator revision, toolkit inputs, command, and any manual adjustments. Seals certify bytes, not generator provenance.

Continuous toolkit QA and broader cybind asset/consumer improvements remain independent follow-ups. This change does not need a generator overhaul or QA directory move to establish the new source ownership. The final generated payload remains the reviewed v12.9.9 import plus previously disclosed overlays and seal normalization.

Concrete defects fixed during this drive

  1. Metadata drift escaped pre-commit and ordinary PR tests. The hook watched pyprojects, but schema validation stopped inspecting their selectors after the SCM simplification. Added an explicit current-tree metadata validator and ran the full existing CI-tool suite in PR CI. Historical configuration loading remains independent of current-tree validation.
  2. Reachable tags could be overridden by a manufactured maintenance version. The old helper compared reachable versions with the fallback and special-cased exact HEAD tags. A descendant of an appropriate earlier post-release tag could incorrectly receive a fabricated next-patch version. The helper now asks Git whether any tag selected by the package's real selector is reachable, then defers to standard SCM progression.
  3. A new Git fixture inherited machine-wide signing settings. Disabled signing only inside the temporary test repository, preserving real commit signing.
  4. Strict tagged-source notes broke real historical releases. v12.9.7 lacks matching notes in its tagged tree, and v12.9.9 lacks separate metapackage notes. Added an explicit legacy-only fallback to exact-version control notes, using the control registry's root; historical metapackages may use matching bindings notes with a visible warning. Empty notes, wrong-version notes, invalid resolver metadata, and registry-bearing new releases remain strict.
  5. Documentation had broken local targets. Added the missing support-page anchor. Comparing the full imported docs with the historical release then exposed two MyST targets and one orphan template warning; the third commit fixes those authored-doc issues. A focused render with production Sphinx/MyST versions reproduces exactly three warnings before the patch and zero afterward, and verifies the HTML links.

Removed five redundant snapshot/static-agreement tests. Retained negative artifact selection, matrix completeness, exact-tag identity, historical-source, and mixed-workplan tests because ordinary happy-path CI does not exercise those failures.

Local validation

  • Checked local_cuda.sh status before local test activity; every check reported active cuda-13-4.conf. No global CUDA switch was performed.
  • Installed the declared ci[test] dependencies into the existing TestVenv after the first collection attempt reported missing PyYAML.
  • Final CI-tool suite: 191 passed, 55 subtests passed; two setuptools-scm deprecation warnings for the existing supported configuration spelling.
  • Full required pre-commit run --all-files passed with only lychee skipped after its separate network run. Generated-file seals, metadata/pin checks, Ruff, mypy, actionlint, and other hooks passed.
  • Full network lychee: 800 successful checks and exactly three expected pre-merge 404s, all canonical main/cuda_bindings_12 links. Removed .lycheeignore permanently. Separately checked the newly tracked release guide and changed documentation; that check passed.
  • Actual archived v12.9.7 and v12.9.9 trees passed the real resolver and release-notes CLIs for both bindings and metapackage. The checks exercise distinct tagged-source and control-tree package roots.
  • Inherited-global-signing regression selection passed. SCM tests cover selected regular/prerelease/post-release tags and descendants, unmatched release families, and unreachable tags.
  • Official seal validation covered 133 marked files across the two roots.
  • Native bindings code did not change during this drive. The CI/tooling/docs changes were validated locally through their own tests, then through hosted build/release execution. Earlier full local native QA belongs to earlier revisions and is not presented as a fresh rebuild of this candidate.

Local logs:

  • /tmp/pr2737_final_ci_tools_20260929.log
  • /tmp/pr2737_precommit_final_clean_20260929.log
  • /tmp/pr2737_precommit_network_20260929.log
  • /tmp/pr2737_precommit_docs_final_20260929.log
  • /tmp/pr2737-docs-anchor-check/before/render.log and /tmp/pr2737-docs-anchor-check/after/render.log

Hosted validation

The product head advanced to 17e19e25b6b20eee6a5c13c8b39befd1b2b11a38 only for the four authored-doc fixes. Native package code, packaging metadata, CI helpers, and production release workflows are byte-identical to b00b677. Normal final-head CI was requested with /ok to test 17e19e25b6b. The earlier /ok to test b00b677be36 run was superseded and cancelled, not recorded as a product failure.

Final-head check Result
Normal CI, attempt 2 108 successful jobs, completed September 29 at 16:07:31 UTC
Security Successful: Pulse and CodeQL pass; suite preflight intentionally skipped
Bandit Successful

After marking the PR ready, a stable, fully paginated check read confirms 121 successful checks, three intentional skips, and none pending or failing. These 124 checks include auxiliary rehearsal checks; normal CI itself has 108 successful jobs. The separate pre-commit.ci - pr commit status passes. The new assignee/labels/milestone check also passes.

The final-head CI metadata/helper gate independently confirms the same 191 tests and 55 subtests passed. The original complete attempt and the failed-job retry are preserved separately; the following section records the two intermittent Windows failures and the investigation rather than hiding them behind the final green result.

Final-head Windows failure investigation

The first observed normal-CI failure was Windows Python 3.14t / CUDA 13.0.2 wheels / A100 MCDM. The jit_lto_fractal.py subprocess exited with 3221225477 (0xC0000005, native access violation), with empty stdout/stderr and no crash stack. The rest of that Core test run reported 3,902 passed, 486 skipped, and two expected failures.

Compared the exact same row against main baseline 36e4d40 and prior PR head 59ff7bd: both had the example pass and reported 3,903 passed, 486 skipped, and two expected failures. All three used published bindings 13.0.3, CuPy 14.2.0, NVRTC 13.0.88, runtime 13.0.96, and nvJitLink 13.4.92. Core source, Pathfinder source, the example, and its test have identical Git object identities between the main baseline and final head. The CUDA 12 imported bindings are not installed in that row. This evidence supports a focused diagnostic rerun; it does not identify the native crash's root cause or justify a speculative code workaround.

The original attempt completed with 108 jobs: 105 successful, two failed Windows test rows, and their derived Check job status failure. The complete paginated attempt-1 records were saved before any retry (/tmp/pr2737-original-ci-attempt1-jobs-pages.json; independently also /tmp/pr2737-final-pr-ci-attempt1-jobs.json). At 15:44:20 UTC, after confirming the exact PR head and unchanged base, the GitHub App accepted a failed-job-only rerun of the original workflow. No successful build/test row was rerun or removed from coverage.

The failed-job retry completed successfully at 16:07:31 UTC. GitHub reports all 108 jobs successful: 105 successful first-attempt jobs retain their original execution timestamps, while only the two failed Windows rows and the aggregate gate execute again. The CUDA 13.0 retry explicitly passes the fractal test and reports 3,903 Core tests passed, 486 skipped, two expected failures, and 15 warnings in 276.51 seconds. The CUDA 13.4 retry explicitly passes the VMM growth case and reports 4,060 Core tests passed, 409 skipped, four expected failures, and 112 warnings in 379.06 seconds. The product source is unchanged throughout; no test suppression, relaxed assertion, or reduced matrix was used. The original failure causes remain unresolved, with the separately confirmed existing ownership defect described below.

A second job failed in Windows Python 3.14t / CUDA 13.4.2 wheels / A100 MCDM: test_vmm_allocator_grow_allocation[handle_type1] (win32_kmt) received CUDA_ERROR_INVALID_VALUE from cuMemAddressFree while releasing a temporary, noncontiguous reservation. The reserve call had succeeded. The remaining Core result was 4,059 passed, 409 skipped, and four expected failures. The identical test passed on main and the previous PR head, each with 4,060 passed. Core source and test blobs are unchanged; driver 596.36, CuPy 14.2.0, and runtime 13.4.92 match. No common cause is established for these two different errors.

Queued x86 L4 rows delayed completion and GitHub rejected a job rerun while the containing workflow remained active. Read-only runner status was unavailable (repository runner API permission denied). Historical successful baseline jobs had already shown 78-162 minute L4 queue delays, so the observed queue alone did not establish an outage. The test matrix was preserved.

A separate Windows diagnostic run uses controller 7ef419f7eb1a0ee8cc1b690487dc9f9f1cf66a1e on rwgk/pr2737-windows-crash-diagnostic-17e19e2. Its one new wrapper calls the unchanged Windows test workflow at final product source 17e19e25b6b20eee6a5c13c8b39befd1b2b11a38, reuses native artifacts from the normal run, preserves the exact original registry/workplan and two failed matrix rows, and adds only PYTHONFAULTHANDLER=1 and PYTHONUNBUFFERED=1. It has read-only repository permissions and no inherited repository secrets. Third-party dependencies still use the normal production constraints, so their resolved versions are compared in the diagnostic logs.

The diagnostic completed green on its first attempt: all three jobs passed. The CUDA 13.0 row explicitly reports the fractal example PARALLEL PASSED, with 3,903 Core tests passed, 486 skipped, and two expected failures. The CUDA 13.4 row explicitly reports the previously failing VMM growth test PARALLEL PASSED, with 4,060 Core tests passed, 409 skipped, and four expected failures. Both used the ordinary four-thread test configuration. The complete package lists immediately before Core are identical to their original jobs (34 packages for CUDA 13.0 and 44 for CUDA 13.4), as are Python 3.14.7 and driver 596.36. The inherited VMM cleanup warnings remain. These results establish that the two failures are intermittent in unchanged source and matching environments; they do not establish either failure's root cause. Evidence: /tmp/pr2737-win-fractal-diagnosis.md, /tmp/pr2737-windows-diagnostic-versions.json, and the two diagnostic excerpts beside them.

Separate pre-existing Core ownership defect

The failure investigation uncovered and independently confirmed a duplicate deallocation attempt in the existing VMM slow-growth path. Buffer ownership captures the resource and size in a C++ deleter. Slow growth explicitly unmaps and frees the old address, then Buffer._clear() resets the owner, invoking its deallocator again. The deallocator can stop at a failed unmap; this is a duplicate cleanup attempt, not proof of a second successful free. Matching destructor warnings appear in both successful baseline runs as well as the failed run. All implicated source files are byte-identical to the main baseline.

The failing temporary-reservation address differs from the warning addresses, so the logs do not establish an address-reuse interleaving or prove this defect caused that failure. No common cause with the JIT subprocess crash is established.

A separate Core correction should preserve the old mapping and owner while transactionally constructing the new mapping, transfer new-resource ownership exactly once, and cover rollback and retained-view behavior. Simply resetting an ownership flag or explicitly closing the old Buffer can invalidate DLPack exports that retain it. This ownership/API follow-up is outside the branch migration's source changes and is recorded for team follow-up.

Exact-source CUDA 12 rehearsal

Source candidate: b00b677be366fd3638c78e26b99aa5b238602646.
Initial disposable controller: 77cfb553ed6076c5d6d23f0e6d97f2b63f953c7f.
Branch: NVIDIA/cuda-python:rwgk/pr2737-cuda12-release-rehearsal-b00b677.
Initial run: https://github.com/NVIDIA/cuda-python/actions/runs/36579081279

The controller changes only five workflow files in a separate worktree. It pins source checkouts and artifact identities to the product candidate, creates synthetic v12.9.99 only in runner clones, uses read-only permissions, physically removes docs publication steps, and contains no package-publishing path. No remote synthetic tag is created.

The rehearsal deliberately verifies rejection of missing synthetic 12.9.99 notes and independently validates real 12.9.9 notes. It does not manufacture a product release note. The intended payload checks cover 18 release wheels, one matching metapackage wheel, wheel METADATA and the stable metapackage's compatible-release bindings requirements (base and [all]), archive source identity, sdists, GPU tests, and documentation.

All 48 original prerequisites passed: 24 native wheel builds, two sdists, 17 GPU test rows, documentation, three matrix jobs, and source resolution. The original rehearsal's final custom metadata assertion was too strict: it expected one ==12.9.99 requirement, while the established stable-release contract correctly emits base and [all] ~=12.9.99 requirements. Both production wheel validators had already passed. The correction was confined to a validation-only controller that reuses the successful artifacts and verifies the actual package contract; no product code or native rebuild was needed.

The first validation-only attempt, 36583210291, exposed another harness-only issue: hosted gh api rejects combining --slurp with --jq. After changing that command to pipe paginated JSON through jq, 36583421384 completed green with controller 64d05e466a0f285b1876ffbfe0f281f5a733b6f9. It verifies all 48 successful original prerequisites and the single known original audit failure, both production wheel validators, wheel metadata, and the exact-source archive. The original run remains recorded as failed; the successful follow-up establishes the corrected artifact audit separately.

Evidence artifact: pr2737-cuda12-release-evidence, ID 11041026359, 113,805,674 bytes, retained until October 29, 2026. GitHub reports archive SHA-256 3469ec9c8691d19dfceb93880904140be56d613e926e2a9bbb8b5b633b837259. Its manifest records source, artifact-run/controller, validation-run/controller, and payload hashes separately.

Downloaded and independently inspected the evidence: all 19 wheel hashes match, all wheel metadata versions are 12.9.99, and the binary matrix is exactly CPython 3.10, 3.11, 3.12, 3.13, 3.14, and free-threaded 3.14 across Linux x86-64, Linux AArch64, and Windows x86-64. Experimental 3.15/3.15t builds are excluded from publication inputs by the production validator. The source archive hash is 172fcc14468358400b93c9d6cf06f3622f2317d10586195c23f8df91f9ef0e43; archival metadata identifies source b00b677 and local tag v12.9.99. Representative registry, package setup, pyproject, and generated driver blobs match that source commit byte-for-byte. Downloaded manifest and inspection record: /tmp/pr2737-final-release-evidence-36583421384/.

This source rehearsal uses a branch push, so it does not establish tag-event run discovery or publication credentials. The separate production dry runs exercise exact-tag lookup with real retained artifacts.

Production release dry runs

Control revision: b00b677be366fd3638c78e26b99aa5b238602646 on isolated branch rwgk/pr2737-release-control-b00b677.
All dispatches explicitly request release-action=dry-run, leave run-id blank, and leave the docs deployment branch blank.

Component Existing tag Successful production dry run
cuda-bindings v13.4.3 36579384563
cuda-python v13.4.3 36579488035
cuda-bindings v12.9.9 36579493491
cuda-python v12.9.9 36579498745

All four completed successfully, including exact-tag CI discovery, notes validation, docs, wheel-matrix checks, and release-artifact preparation. PyPI/TestPyPI publication was skipped; no GitHub release or docs deployment was created.

Exact source/artifact lineage: v13.4.3 = 972ee3b15f4f120f0f99e9d698a75f0e19331b0e, CI 35802685334; v12.9.9 = 89713a7c8bf61037f6a0375ab611778c21f6f9cd, CI 35803298412. Both existing tags predate the new registry. These runs exercise the candidate control implementation against actual legacy sources; the separate exact-source rehearsal covers the new two-root source layout.

Final-source documentation refresh

Final source: 17e19e25b6b20eee6a5c13c8b39befd1b2b11a38. Controller: fcc602d155e5433ef1f0b5514dd763eb8ae388bb. Run: https://github.com/NVIDIA/cuda-python/actions/runs/36581936586. The two-file disposable controller proves the source delta contains only the four authored docs, reuses unchanged native wheels from the original rehearsal, builds full release docs from the final source, and checks both repaired links in the actual HTML. This is not represented as a native-wheel rebuild at the final docs-only SHA.

All three jobs passed. Sphinx warnings decreased from 96 to 93; the three authored-doc defects are fixed. Remaining generated-API warning categories match the historical v12.9.9 source. Duplicate object descriptions are more numerous because this tree retains more release-note documents. The full docs build is successful, not warning-free.

Review disposition

Resolved all 45 threads that were open at the initial audit after checking the implementation, documented decisions, relevant validation, and fresh discussion state. GitHub now shows 52 of 52 threads resolved, including the seven that were already resolved. The PR body contains a grouped disposition map with permanent source links; the appendix below records all 45 individual decisions. New comments and thread state were checked before mutations. No thread reply or unrelated issue/comment was posted; the only new PR comments were the two expressly requested /ok to test triggers.

Author-side thread resolution is distinct from human approval. No review was dismissed and no approval was represented as granted. The PR was not merged.

Remaining boundaries

  • After merge, check the three new canonical main-branch URLs again.
  • Two inherited generated NVRTC documentation entries refer to functions absent from the CUDA 12 module. They need a generator-side correction; this drive does not hand-edit sealed generated docs.
  • Existing production archive checksum companions contain raw digests, not conventional filename-bearing sha256sum -c input.
  • CUDA 12 README links intentionally remain at published 12.9.7 docs: direct network checks found 12.9.7 HTTP 200 and 12.9.8/12.9.9 HTTP 404.
  • Short-lived rehearsal/control branches are retained as validation evidence. No existing branch/tag was force-pushed or deleted.
  • The manual backport action is statically validated against its pinned implementation; no artificial backport PR was opened solely to exercise a team-facing mutation.

Final repository and PR state

  • Product head: 17e19e25b6b20eee6a5c13c8b39befd1b2b11a38; base main remains 36e4d40a664f08ca88b30a50c3553da56d4ef3c2.
  • PR is open, ready for review (draft=false), and mergeable without conflicts. GitHub still reports CHANGES_REQUESTED / BLOCKED; renewed reviewer approval remains outstanding.
  • All 52 review threads are resolved. No reviewer approval was manufactured or dismissed.
  • The tracked working tree is clean. Local agent/cuda-bindings-12-on-main retains tracking of origin/agent/cuda-bindings-12-on-main, and the PR fork head matches the tested product head.
  • Three product commits were added and pushed. Four isolated canonical validation branches retain the release-control, CUDA 12 rehearsal/audit, final-docs refresh, and Windows diagnostic evidence. No existing branch/tag was force-pushed or deleted.
  • No merge, remote version tag, package publication, GitHub release, docs deployment, or global CUDA toolkit switch was performed.

Appendix: individual review dispositions

The PR description contains the grouped review map. These individual decisions cover the 45 threads that were open at the initial audit; they do not imply reviewer approval.

Review thread Author-side disposition
3916239618 CI helpers are a real repository-private distribution, installed editable with declared runtime/test dependencies.
3916306849 Removed the standalone release resolver and redundant JSON-to-environment reconstruction. The purpose-specific write-github-env operation validates the selected record; JSON remains only at structured workflow boundaries.
3916702314 An explicit current-tree metadata guard compares registry minor-family selectors with bindings/metapackage SCM metadata and maintenance fallback/Pixi versions; it is separate from historical schema loading.
3916714594 PEP 440 interpretation uses packaging.version.Version; release routing additionally requires canonical tag spelling and rejects local-version upload tags.
3916813446 Bindings/metapackage rebuilds are selected by root. Normal bindings-source changes still build both dependent Core ABI variants; the author does not claim complete CI independence.
3916830273 Shared registry/version helpers live in the installed ci.tools package rather than relying on ad hoc script imports.
3916893027 Retain runtime tagged-source resolution: a dispatch control revision can differ from the source release tag, so precomputing today's registry cannot establish the historical package/layout/toolkit. The supported compatibility boundary is documented.
3917025344 The drift guard now runs directly in pre-commit and per-PR CI, including the complete CI-tool test suite; metadata agreement is no longer enforced only by nightly static assertions.
3917038211 CI passes a release tag only when github.ref_type is tag; branches whose names begin with v do not trigger release routing.
3917048863 Linux and Windows sdist matrices enumerate the validated two-root registry; per-root workplan gates select execution without constructing an empty matrix.
3917053836 All component artifact selection excludes names ending in -tests before download, preventing test wheels from entering publication inputs.
3917070013 Artifact mode requires exactly one local Pathfinder wheel. Published mode is explicit; a missing or duplicate artifact cannot silently fall back to PyPI.
3917080542 The Pixi checker validates every registered bindings root and matching Core CUDA variant; both roots are included in the pre-commit inputs.
3917089956 Removed the broad shared-files equality/symlink checker rather than retaining an incorrect invariant. Shared maintenance guidance now requires semantic applicability review and permits narrowly scoped equality checks only where justified.
3917097612 CUDA_PYTHON_ARTIFACT_NAME is emitted only for local bindings using the registered build toolkit; published bindings no longer invent a local artifact name.
3917103010 The registry explicitly supports exactly one current and one maintenance root with distinct CUDA majors. It centralizes physical paths and roles; arbitrary N-line support is not promised.
3917111123 Replaced the obsolete contributing diagram with the current package-selection, artifact, dry-run and publication flow. Broader diagram elaboration can remain in #2740.
3917119898 Removed the obsolete installer helper. Retained TOML readers use tomllib rather than regex-based TOML parsing.
3931004805 Adopted the proper-package option with editable installation and declared test extras, matching the shared-helper architecture.
3931004808 Removed the generic echo-through package-json/github-env options; write-github-env is a dedicated operation with a concrete consumer contract.
3931004811 The earlier response about regex validation is superseded: the final guard checks the default-SCM selectors, fallback metadata and standalone metapackage agreement, with negative drift cases.
3972240690 Linux and Windows test gates index each row's bindings root and Core ABI variant; mixed bindings-source/Core-test regression coverage is retained.
3972240696 Release validation derives the expected Python/platform/ABI matrix from tagged workflow metadata and rejects missing, extra and duplicate wheel targets.
3972240701 Dependent component releases resolve their bindings dependency from that component's tagged source, using its current role or recognized legacy metadata, rather than today's control registry.
3972240709 The tagged-source resolver probes both versions.yml and versions.json and preserves the historical toolkit pin. Explicit compatibility fallbacks remain bounded; current metadata does not overwrite recognized historical metadata.
3972240718 Both bindings docs builders preserve .dev suffixes when choosing the docs version path, avoiding occupation of a stable version path by a development tag.
3972240724 CUDA 12 installation examples pin the 12.9 line; README/DESCRIPTION links target valid versioned 12.9.7 docs instead of latest CUDA 13 docs. This disposition does not claim those links point to the newest published patch.
3972240732 The CUDA 12 NVML test handles unavailable PCI information, skips Orin/Thor naming mismatches and compares visible CUDA devices against the NVML superset.
3972240736 Temporary repositories disable inherited commit/tag signing in SCM/tag-selection/run-lookup fixtures. The inherited-signing regression selection passed.
3972240741 Removed the tracked temporary .lycheeignore file. Final full pre-commit passed with lychee skipped; a separate network-enabled link scan reported 800 successes and only three expected pre-merge main-path 404s. These are reported, not hidden by a new ignore file.
3990562921 Artifact lookup requires a successful push run for the exact tag and source SHA; same-SHA sibling tags are distinguished. The policy releases each line independently and does not require both versions to share a commit.
4030956358 Removed transient import/review history from the maintenance guide; it now identifies the root, integration policy and lasting shared instructions.
4030959650 The maintenance guide now gives ongoing maintenance/release instructions and links common policy instead of addressing this PR's reviewer.
4030963901 Generation and handwritten applicability instructions are centralized in shared CI guidance and apply to both roots.
4031036494 Replaced the obsolete fixed-12.9 bot with explicit dispatch of a merged PR to one existing release branch. Labels cannot add targets; no automatic merge is enabled. Documented manual conflict/generated/workflow-file handling and return-to-main responsibility.
4031083254 Retain cuda_bindings_12 as a stable major identity; current/maintenance remain explicit lifecycle roles. A prev rename would obscure identity without simplifying the supported two-role contract; major rollover is documented.
4031089226 Keep the current minor in the source-build --match selector so a new target cannot accidentally derive its version from a preceding minor's reachable tags. The metadata guard makes coordinated registry/packaging updates mandatory.
4031114469 CUDA_PYTHON_BUILD_MAJOR is always required; absent or unsupported values fail instead of defaulting to a major.
4031119779 Keep the standalone metapackage's minor-family selector map because its sdist cannot import repository CI metadata. Validate exact agreement against both bindings roots; keep setuptools-scm's standard parser.
4031120234 Build/test environment values now come from named jq object entries instead of a positional read-variable/array correspondence.
4031135974 Retain separate generated-file ignore lists while the CUDA 12 and current runtime generation layouts materially differ; Mike accepted this bounded choice in the discussion. Consolidation can follow actual layout convergence.
4062051063 Aligned the 12.9.10.dev0 fallback across packaging inputs, then corrected the override to apply only when no tag matching the actual package selector is reachable. Matching earlier regular/prerelease/postrelease tags and descendants now keep standard SCM progression.
4062130293 Metapackage builds use standard setuptools-scm tag parsing, preserving prerelease and postrelease suffixes. Real SCM parser integration cases remain.
4062428956 Release selection rejects noncanonical leading-zero spellings before PEP 440 interpretation, avoiding normalization disagreement. Source builds continue to use the standard SCM parser.
4063090459 A general deterministic equivalence check for handwritten code is unavailable. Require explicit cross-root applicability and reviewer verification; generated-file seals establish content integrity, while revision/input records establish generation provenance.

@rwgk

rwgk commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

The historical 12.9.x branch receives no further routine or emergency backports

One thing I realized about this is that if we do need a backport to 12.9, we're starting from a state where the 13.x code may not currently be producing a green run. Based on my read of this that will incur a full 13.x rebuild/test. There's something a little tricky to me about this coupling that feels like it could cause us to block a 12.x fix on 13.x CI jobs just due to the nature of the situation, though I don't have a great suggestion here.

@brandon-b-miller, GPT-6-Astra ultra implemented a practical compromise. In its own words:

Your concern is real: an ordinary CUDA 12 maintenance PR can still encounter CUDA 13/Core CI failures. The proposal retains that integration testing and adds a release path that can proceed from a tested baseline.

The compromise has three parts:

  • Keep normal development on main. Bindings changes continue to exercise affected Core consumers, so integration regressions remain visible.
  • Use short release branches when needed. Stabilization or urgent fixes can proceed from a tested commit containing the new package layout, isolated from subsequent unrelated changes on main. Branch-first fixes require a linked follow-up PR to reconcile them back into main, with applicability assessed for both bindings roots.
  • Scope release-tag CI to the selected line. A bindings tag builds and tests that bindings package and its matching cuda-python metapackage, using published Pathfinder. Core builds, runtime tests, API checks, and docs are excluded from that release run.

This addresses the release-stage coupling and provides a practical way around unrelated breakage on advancing main. It does not eliminate all coupling: PRs still need their normal review and CI, and repository-wide checks—including Core lint/type checks—still run on release tags.

So the intended guarantee is that a bindings release does not require a Core build, test run, or release. It is not a guarantee that every possible Core problem is irrelevant to the process.

@rwgk

rwgk commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

@leofang Following your offline question about whether we should continue #2737, I asked Codex for a deep analysis of the 12.9.x history, related PRs/discussions, and the generator/QA workflow.

Its conclusion: keep #2737’s direction, combined with explicit release branches for stabilization and urgent fixes.

The main reasons:

  • CUDA 12.9 is an actively supported major line. It has received new bindings capabilities, Python support, and ecosystem updates. Maintaining it involves substantial ongoing integration work.
  • The history shows recurring coordination costs: diverging CI/release infrastructure, cross-branch artifact dependencies, and generated changes requiring target-specific adaptation. Better backport automation helps, but several of these tasks require more than transporting commits.
  • Release branches remain useful. They let us freeze a tested baseline and select fixes while development continues on main.

The proposed division is therefore: develop the two supported majors together on main; stabilize and repair particular releases on branches when needed.

The revised PR implements that direction with focused bindings-release CI, a manual backport workflow, and a short release guide. Normal PRs retain Core integration checks, and generated changes still need explicit applicability review.

That gives us a concrete reason to finish #2737 while continuing to improve branch automation and generator coordination.

rwgk added 2 commits October 3, 2026 22:00
Integrate main through ab9e20f. Preserve the registry-driven dual-root build and release model while adopting Core bindings floors, uv builds, wheel-source provenance, compiler/cache fixes, and docs deployment concurrency.

Port applicable shared build helpers to CUDA 12 and cover schema-2 floors and merged-wheel bootstrap files with regression tests. The only new 12.9.x commit (1635cf2) updates Actions pins; its applicable updates are included without restoring retired branch workflows.
Preserve the configuration around size_t, bool, and string roundtrip tests so random ordering cannot disable compatibility mode or leave invalid settings for later driver opens. Restore values in finally blocks and keep valid defaults for empty string settings rejected by cuFile setters.

rwgk commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 07845c5

@copy-pr-bot

copy-pr-bot Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

/ok to test 07845c5

@rwgk, there was an error processing your request: E2

See the following link for more information: https://docs.gha-runners.nvidia.com/cpr/e/2/

rwgk commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 07845c5

rwgk commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 83ae256

rwgk commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 5b41dd1

rwgk commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test be28657

@rwgk

rwgk commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

Independent "full review" with Fable 5 ( claude-fable-5, 429ce6ca-7e50-4164-a7cc-4d506707e590):


Review complete — all five parallel review passes are in, and I verified the two highest-value findings directly in the code. Bottom line: no critical defects; the PR's core machinery (tag-family SCM selection, the self-disabling CUDA 12 fallback, release provenance validation, the registry/metadata consistency checks) holds up under both code reading and actual execution. One major finding in the release workflows should be fixed before merge; the rest are minor robustness/asymmetry items.

Findings

  1. Major — unqualified tag checkouts let a same-named branch shadow the release tag. .github/workflows/release.yml:69 (also :196, :284, :350), .github/workflows/release-upload.yml:63, and .github/workflows/build-docs.yml:70 (also :436) check out the release source with ref: ${{ inputs.git-tag }}. actions/checkout resolves an unqualified ref as a branch first, tag second, so a branch named v12.9.10 (accidental prep branch, or anyone with push access) silently supplies ci/versions.yml, release notes, and the wheel-matrix expectations, while lookup-run-id, the tag-SHA check, and git archive use the real tag. This partially defeats the PR's own guarantee that configuration comes from the tagged source. .github/workflows/release-cuda-pathfinder.yml:75 already does it right with ref: refs/tags/... — a one-line fix in each spot. I confirmed all seven occurrences myself.

  2. Minor — the metadata validator accepts the non-excluding selector form for the maintenance root. ci/tools/bindings_config.py:236 allows either v{ctk}.* or v{ctk}.[1-9]* for any root (confirmed by reading the code). If cuda_bindings_12's --match were ever edited to v12.9.* (with setup.py in lockstep), the check still passes, the reachable v12.9.0 baseline re-enables, the fallback disables, and setuptools-scm derives 12.9.1.devN — a silent version regression below published 12.9.10.dev builds. Tie the [1-9] form to release_status == maintenance (and check the current root has no fallback_version). This guards exactly the scenario the fallback mechanism exists to prevent.

  3. Minor — cuda_bindings_12's pixi test task runs benchmarks hot. cuda_bindings_12/pyproject.toml has no [tool.pytest.ini_options] (unlike cuda_bindings/pyproject.toml:88), so pixi run -e cu12 test resolves to the repo-root pytest.ini: benchmarks/pytest.ini's --benchmark-skip and tests/pytest.ini options are never loaded, benchmarks run at full iteration counts, and the task comment "(ignore by default config)" copied from the 13 root is inaccurate there (cuda_bindings_12/pixi.toml:149).

  4. Minor — release.yml draft detection races and paginates poorly. .github/workflows/release.yml:160 builds parallel tags[]/is_draft[] arrays from two separate gh release list calls with the default limit 30; >30 releases can hide a draft (fails closed), and a release created between the calls misaligns the arrays. One gh release view <tag> call (as the pathfinder workflow does) fixes both.

  5. Minor — wheel-matrix exclusions are duplicated by convention. ci/tools/validate_release_wheels.py:27,190,197 hardcodes the 3.15 prefix, 3.10-on-win-arm64, and toolkit≥13.4 win-arm64 gates that live as ${{ }} expressions in build-wheel.yml; the python list is read from the tagged source but these exclusions come from the control checkout, so a tag with different workflow gating misvalidates (loudly, not silently).

  6. Minor — tag-move TOCTOU between run-ID validation and publish. determine-run-id enforces exact-tag/exact-SHA correctly, but the publish jobs re-resolve inputs.git-tag minutes later; a force-moved tag mid-run would pair validated wheels with a different tag source. Mitigated by the tags-immutable policy; an in-job assertion that git rev-parse refs/tags/$TAG equals the validated run's head SHA (or a tag-protection ruleset) closes it.

  7. Minor — residual inline ${{ }} shell interpolation. .github/workflows/ci.yml:48 interpolates github.ref_name into a grep <<< under workflow_dispatch (a crafted branch name injects into a job holding a limited-scope token), and ci.yml:342 interpolates a tag name into a run block — inconsistent with the careful env: routing used everywhere else in the PR.

  8. Minor — packaging asymmetries between the two roots worth a deliberate yes/no each: cuda_python/setup.py:19 makes CUDA_PYTHON_BUILD_MAJOR mandatory and undocumented, so a plain pip install ./cuda_python (or any future metapackage sdist) fails at setup.py; cuda_bindings_12/pyproject.toml:49 keeps a published test extra now carrying an exact pytest==9.1.0 pin (13 root uses unpublished dependency-groups — pick one convention); cuda_bindings_12/pyproject.toml:20 silently drops Python 3.9 relative to v12.9.9 (requires-python = ">=3.10") in a maintenance line; cuda_bindings_12/pixi.toml:12 pins cuda-version = "12.*" while build_hooks.py hard-requires 12.9 headers, and check_pixi_cuda_version.py's _pin_covers_toolkit now accepts major-only pins, weakening what that check can catch.

  9. Minor — test-env pin duplicated without a sync tie. pytest-run-parallel==0.10.0 appears in ci/tools/run-tests:28 (the legacy-extras branch used by cuda_bindings_12) and in cuda_bindings/pyproject.toml:57's test-ft group; a bump in one skews free-threaded test envs between roots.

  10. Minor — in test_cufile.py the string-parameter restore now sits in a finally without a cuFileError catch (cuda_bindings_12/tests/test_cufile.py:1716), so a host whose cufile.json ships a value the setter later rejects turns a passing round-trip into an error (main tolerates this). Also thread_unsafe is unregistered in cuda_bindings_12/tests/pytest.ini (warning-only; matches main's convention). Otherwise the three cuFile commits are correct and actually stricter than main's equivalents — restores run via per-parameter try/finally, env handled via monkeypatch, and the thread_unsafe serialization is wired to pytest-run-parallel, the parallel mechanism CI actually uses.

  11. Minor — small polish items: ci/tools/compute_ci_plan.py:319's load_config() sits outside the try that maps config errors to clean parser.error exits; validate_release_wheels keeps a latent, now effectively unusable --component all path that accepts unregistered v-tags; the check-bindings-config pre-commit filter (.pre-commit-config.yaml:68) doesn't re-trigger on edits to the validator itself; cuda_bindings_12/build_hooks.py's _INSTALL_URL points at the 12.9.7 docs page; release-upload.yml uploads the source archive before wheel validation, so a failed validation leaves the tarball on the draft.

SYNCED-block verification (per repo policy)

Groups compared: PYTEST PLUGIN BOOTSTRAP — 3 copies (cuda_bindings/tests/conftest.py:15, cuda_bindings_12/tests/conftest.py:8, cuda_core/tests/conftest.py:14), extracted and diffed byte-for-byte: identical. The group is newly introduced by this PR; no markers removed or renamed anywhere. The build_hooks "shared build helpers" block (3 copies across cuda_bindings, cuda_bindings_12, cuda_core) uses its own marker convention enforced by toolshed/check_build_hooks_sync.py, which passes — stronger than prose markers, though a second convention. Candidate drift risks: four byte-identical newly copied files carry no markers or checker — _internal/_fast_enum.py, tests/utils/check_cyclical_import.py, tests/nvml/test_page_retirement.py (the lone identical file in an otherwise-divergent directory — easiest to drift), and MANIFEST.in; plus tests/cython/build_tests.py differing only in the cache-key string. Worth considering markers for the first three.

Import fidelity and the rest

The cuda_bindings_12 tree is a high-fidelity import of upstream v12.9.9: every generated binding module and generated doc is byte-identical to the tag, and all 79 differing files decompose cleanly into the declared overlays (coredump buffer-lifetime fix, str/bytes nested-resource fix with paired tests, NVML test port, cuFile isolation work, the runtime.pyx.in seal correction — seal checker passes, and monorepo packaging/docs adaptations). No unexplained source changes. Test authorship markers are present on every newly added test checked (directly or via class-level markers). The two stale NVRTC doc entries and the 12.9.7 README links match the known boundaries stated in the PR description. All 52 PR review threads are resolved.

The SCM design's key question — "does the custom fallback reliably get out of the way once standard Git-derived versioning can work?" — checks out: the fallback probe uses git tag --merged --list <selector> with the same wildmatch semantics as git describe --match, so the probe and setuptools-scm cannot disagree on tag visibility; this was verified empirically (annotated/lightweight tags, tags on HEAD vs ancestors, unreachable tags, the excluded v12.9.0 baseline, prerelease/postrelease descendants), and get_version() run against this tree with the 12 root's exact options produced the expected 12.9.10.dev… fallback result. One residual: that was verified on setuptools-scm 10.2.1 while the build floor allows >=8 — worth a one-time check in the pinned build env. The ci/tools suite (214 tests, 55 subtests) passes locally and the tests are genuinely strong — real git repos, real bash scripts under instrumented shims, mutation-style drift cases, no vacuous tests found.

Open questions

  • Is the Python 3.9 drop in the 12.9 maintenance line (finding 8) deliberate? It's unflagged in the PR description.
  • Is the major-only cuda-version = "12.*" pixi pin (vs the 13 root's exact 13.4.*) the intended invariant for the maintenance root?

Overall this is unusually carefully engineered for a change of this size — fail-closed defaults, env-var routing of untrusted input, provenance enforced end-to-end from tag to SHA to run to wheel matrix. The recurring structural theme behind most minor findings is invariants enforced by convention in two or three places instead of derived from one source (findings 2, 5, 9). I'd fix finding 1 (refs/tags/ qualification) and finding 2 (selector-form/role coupling) before merge; everything else can reasonably be follow-up.

@rwgk

rwgk commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

codex (01a10935-1727-7170-b707-08d725a9f457) analysis of

CI / Test win-64 / Python 3.15, CUDA 13.4.2 (wheels), GPU l4 (MCDM) Failing


This is a test-dependency installation failure. It is connected to PR 2737: the PR adds PyYAML==6.0.3 to Core’s test dependencies for registry validation.

The job log shows:

  • Pathfinder and bindings tests pass.
  • Core’s dependency installation downloads PyYAML’s source archive.
  • Building its optional yaml._yaml extension fails with “Microsoft Visual C++ 14.0 or greater is required.”
  • Core tests never start.

PyYAML 6.0.3 has no Python 3.15 wheels, which explains the source build.

I recommend using PyYAML’s pure-Python implementation for Windows/Python 3.15. Append this line to the existing Windows Python 3.15 setup step:

echo "PYYAML_FORCE_LIBYAML=0" >> "$GITHUB_ENV"

PyYAML supports this setting. It preserves the dependency and registry tests while avoiding extension compilation.

I verified that the setting builds a pure-Python wheel with an unavailable compiler and that YAML parsing works. That verification used Linux/Python 3.12; the Windows/Python 3.15 job still needs a rerun after the adjustment. The current failure provides no evidence of a CUDA implementation regression.

rwgk added 3 commits October 4, 2026 17:44
Disable the optional LibYAML extension before test dependency installation. Python 3.15 has no matching PyYAML wheel, and GPU test runners do not configure MSVC.

Validated a source-built pure-Python wheel with an unavailable compiler; 268 CI-tool and Core tests plus 55 subtests passed against it.
Prevent same-named branches from shadowing release tags when resolving configuration, notes, docs, and source archives. Preserve branch and default-ref behavior for ordinary docs builds.

Validated with the pinned checkout implementation and real same-name branch/tag collisions; six cases and actionlint passed.
Require the maintenance selector to exclude the pre-maintenance .0 baseline, even when bindings and metapackage selectors are changed together. Require the current selector to include .0 and reject a current-root fallback_version.

Three regression cases failed before the fix. Integrated CI-tool and Core floor tests passed with pure-Python PyYAML.

rwgk commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 6c3de41

@rwgk

rwgk commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

Fable 5 ( claude-fable-5, 429ce6ca-7e50-4164-a7cc-4d506707e590):

Re-review complete: all three new commits are correct, both actionable findings are properly fixed, and the Python 3.15 Windows job now passes. No new findings.

What I verified on the fresh head (6c3de41)

  • a83b550 (tag-ref qualification) fixes the major finding fully. All five release.yml checkouts and release-upload.yml:63 now use ref: refs/tags/${{ inputs.git-tag }}; the pathfinder workflow's archive job additionally qualifies both the checkout and the git archive ref. build-docs.yml uses inputs.is-release && format('refs/tags/{0}', inputs.git-tag) || inputs.git-tag — I checked the ternary is type-safe (is-release is a declared type: boolean, so a string "false" footgun doesn't apply) and both release callers pass is-release: true. The one path still using an unqualified ref is ci.yml's ordinary tag-push docs build (is-release false), which the commit message calls out as deliberate; that path only feeds preview/CI docs, not release artifacts, so I agree it's acceptable.
  • 6c3de41 (selector-role enforcement) implements exactly the recommended closure of the version-regression hole: the maintenance root must use v{ctk}.[1-9]*, the current root must use v{ctk}.*, and a fallback_version on the current root is now rejected (ci/tools/bindings_config.py:237). The new regression test changes both the pyproject and cuda_python/setup.py in lockstep — the precise scenario the old check missed — and asserts rejection in both directions. I ran the full ci-tools suite in a temporary worktree at the new head: 217 passed, 55 subtests (up 3 from the prior 214, matching the new cases). New/modified tests carry @pytest.mark.agent_authored markers per policy.
  • 71d782a (PyYAML) sets PYYAML_FORCE_LIBYAML=0 in the existing Windows Python 3.15 setup step of test-wheel-windows.yml, matching the root-cause analysis in the linked comment (no cp315 PyYAML wheels + no MSVC on GPU runners). Correctly scoped: Linux 3.15 jobs build the extension fine with gcc and were already green.
  • CI on the new head: 120 checks pass, 3 skipped (conditional jobs), 0 failures — including the previously failing Test win-64 / Python 3.15, CUDA 13.4.2 (wheels), GPU l4 (MCDM) job, now green.

Status of the remaining minor findings — unchanged by these commits, consistent with your note that only the two actionable ones were addressed. The ones I'd still keep on a follow-up list, roughly in order of value: the cuda_bindings_12 pixi test task resolving to the repo-root pytest.ini (benchmarks run un-skipped), the undocumented mandatory CUDA_PYTHON_BUILD_MAJOR (metapackage sdist installability), the published exact-pinned test extra and the unflagged Python 3.9 drop in the maintenance line, the gh release list draft-detection race, and SYNCED markers for the three byte-identical unmarked copies (_fast_enum.py, check_cyclical_import.py, tests/nvml/test_page_retirement.py). None block merge.

I cleaned up the temporary worktree I used for testing; your checkout is untouched (still at be2865709db locally — git pull when you want the three new commits here).

@rwgk rwgk added the PR review get-together Mark PRs you'd like the team to review at the weekly PR review get-together. label Oct 5, 2026
@rparolin

rparolin commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

My concern with this PR is no one is going to do a decent job of reviewing a 302 file change. I'd would highly encourage breaking this change up into smaller changes that can be atomically reviewed and submitted. Reading through the 'Decision Implemented' section seems like those would be good candidates to explore as atomic changes. I'd track them as sub-work of a larger EPIC.

cc: @leofang

@rparolin
rparolin self-requested a review October 5, 2026 15:44

@rparolin rparolin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please break this PR up into smaller reviewable chunks.

@rwgk

rwgk commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

My concern with this PR is no one is going to do a decent job of reviewing a 302 file change. I'd would highly encourage breaking this change up into smaller changes that can be atomically reviewed and submitted.

There is already a narrated "Refreshed six-layer review aid" in the PR description that serves that purpose.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/CD CI/CD infrastructure cuda.bindings Everything related to the cuda.bindings module cuda.core Everything related to the cuda.core module cuda.pathfinder Everything related to the cuda.pathfinder module enhancement Any code-related improvements PR review get-together Mark PRs you'd like the team to review at the weekly PR review get-together.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit cuda-bindings branching strategy

7 participants