diff --git a/.github/RELEASE-bindings.md b/.github/RELEASE-bindings.md new file mode 100644 index 00000000000..df8c47badcd --- /dev/null +++ b/.github/RELEASE-bindings.md @@ -0,0 +1,108 @@ + + +# Releasing CUDA bindings + +## Choose the release scope and source + +Develop the current and maintenance CUDA major lines together on `main`, in +the two package roots listed in [`ci/versions.yml`](../ci/versions.yml). +Release each line independently. A bindings release also needs its matching +`cuda-python` metapackage release; it does not require a release of the other +CUDA major, `cuda-core`, or `cuda-pathfinder`. + +Major-line maintenance may include selected API, Python, platform, or other +compatibility changes. Decide those changes explicitly and describe them in +the release notes. Once a patch release is frozen, admit only its approved +fixes and release prerequisites. Do not infer patch-release scope solely +from the registry's `maintenance` role. + +For an ordinary release, select a tested commit on `main`. If stabilization +must continue while development advances, create a short release branch such +as `release/bindings-12.9.11` from the chosen commit. For an emergency after a +release, start from its exact tag, provided that tag contains the new package +layout. For the first release after this transition, use a validated commit +containing both roots. Keep routine development on `main`; the historical +`12.9.x` branch stays frozen except for emergency fixes using compatible +historical tooling. Reconcile those fixes into the main-tree maintenance +root. Keep the package layout and release tooling together on new release branches. + +Record the source commit, intended tag, selected package root, release owner, +and accepted changes in the release checklist. A branch is a temporary scope +boundary, not a separate long-term home for shared infrastructure. + +## Move fixes between integration and release branches + +Prefer a reviewed fix on `main`, then backport it to the selected release +branch. Run **CI: Backport a merged PR to a release branch** from the Actions +tab on `main`, supplying the merged PR number and one existing target branch. +The workflow opens a PR; it does not merge or release the result. Inspect the +diff, request CI using the normal PR approval procedure, and review it before +merging. Workflow-file changes require a manual backport with appropriate +credentials. Conflicts and toolkit-specific generated changes require an +explicitly reviewed adaptation. + +If urgency requires a fix on the release branch first, link a follow-up PR +reconciling the fix back into `main` before closing the release checklist. In either +direction, assess both bindings roots and record why a change applies to one +or both. Regenerate affected generated files from the intended toolkit and +cybind inputs instead of blindly copying generated output between majors. +See the [shared maintenance policy](../ci/README.md#maintaining-both-bindings-roots). + +## Validate and publish the selected line + +1. Finalize the bindings and metapackage release notes, dependency constraints, + and selected toolkit pin in the release source tree. The registry and + packaging metadata must agree. Run the CI-tool suite and pre-commit checks. +2. Test the candidate through a reviewed PR or manual CI dispatch on its + branch. Normal development CI includes dependent packages and may cover + both majors. Resolve failures in affected code before selecting the tag. +3. Create the approved immutable `vX.Y.Z` tag at the selected source commit. + The tag-triggered CI selects that line's bindings and metapackage, validates + them with the published Pathfinder dependency, and builds release artifacts. + The tag does not have to be on `main`. Wait for this exact tag's CI to pass. +4. Run **CI: Release** with `release-action=dry-run`, the tag, and + `component=cuda-bindings`; repeat for `cuda-python`. Leave `run-id` blank + to exercise automatic lookup, and leave `dry-run-docs-branch` blank to avoid + deploying docs. The workflow verifies a successful tag-triggered CI run + with the exact source SHA, validates artifacts, and builds docs. +5. Review the dry runs, then separately approve and run `full-release` for + each component under the team's release procedure. A successful candidate + rehearsal or ordinary branch CI is not a substitute for exact-tag CI. +6. After both component releases succeed, review and publish the shared + `vX.Y.Z` GitHub Release draft. Check its release notes, versioned + documentation links, source archive, checksum, and wheels. These component + workflows leave the draft for the release owner to publish. +7. Finish post-release QA and announcements, return every applicable fix to + `main`, and close the stabilization effort. Retain immutable tags and the + branch history needed for diagnosis. + +For either bindings line, add the released version to +[`cuda_bindings_13/docs/nv-versions.json`](../cuda_bindings_13/docs/nv-versions.json) +and its matching metapackage version to +[`cuda_python/docs/nv-versions.json`](../cuda_python/docs/nv-versions.json) +on `main`. Documentation deployments from `main` own these shared version +selectors. Release deployments publish versioned pages without replacing the +selectors or shared `latest` pages; updating a selector only on a stabilization +branch will not update the public selector. + +The workflow revision used for a release is its **control revision**; the +tagged commit is its **source revision**. Record both and the artifact CI run +ID. Release routing uses the package layout and toolkit settings in +`ci/versions.yml` at the release tag. The current tooling requires a valid +schema-2 registry in that source, for both dry runs and publication, including +Core and Pathfinder releases. Tags from before this registry was introduced +require compatible historical tooling; the current workflow configuration +cannot supply missing tagged configuration. Published releases remain unchanged. + +In **CI: Release**, normal bindings and metapackage releases each require +their own exact-version, nonempty release notes in the tagged source. Notes +from the workflow control revision or a different component cannot fill a gap. +Preserve their existing exemption for `.postN` releases, which do not require +new notes. + +Local synthetic tags used in publication-incapable rehearsals must remain local; +they do not authorize publishing a package, creating a remote tag, or moving +an existing tag. diff --git a/.github/RELEASE-core.md b/.github/RELEASE-core.md index 498a8e2c551..0e85b44a9a5 100644 --- a/.github/RELEASE-core.md +++ b/.github/RELEASE-core.md @@ -3,11 +3,10 @@ # cuda.core Release Process -This document covers the `cuda.core` release process. For other packages: -`cuda-bindings` and `cuda-python` involve a private repository and are not -documented here; `cuda-pathfinder` is largely automated by the -[CI: Release](workflows/release.yml) -workflow. +This document covers the `cuda.core` release process. See the +[bindings release guide](RELEASE-bindings.md) for `cuda-bindings` and +`cuda-python`. The `cuda-pathfinder` release process is largely automated by +the [CI: Release](workflows/release.yml) workflow. To release `cuda-pathfinder`, dispatch **CI: Release** with `component` set to `cuda-pathfinder`, `release-action` set @@ -176,21 +175,29 @@ Pushing the tag triggers a CI run automatically. Monitor it in the ## Upload wheels to PyPI -This is a single `CI: Release` workflow run with two sequential stages: -publish to TestPyPI, then publish the same wheel set to PyPI. +First validate the release with a dry run. After reviewing that result, a +`full-release` run publishes to TestPyPI, then publishes the same wheel set to +PyPI. 1. Go to **Actions > CI: Release** and run the workflow with: - **Component**: `cuda-core` - **The release git tag**: `cuda-core-v0.6.0` + - **What to run**: `dry-run` - The workflow automatically looks up the successful tag-triggered CI run - for the selected release tag. + Leave `run-id` blank to exercise automatic lookup of the successful + tag-triggered CI run. Leave `dry-run-docs-branch` blank to validate the docs + without deploying them. -2. Wait for the workflow to complete. It will: - - publish the selected wheels to TestPyPI - - publish the same wheel set to PyPI +2. Review the completed dry run, then approve publication under the team's + release procedure and run the workflow for the same component and tag with + **What to run** set to `full-release`. -3. After completion, verify the final PyPI upload: +3. Wait for that run to complete. It deploys versioned documentation and uploads + the source archive, checksum, and wheels to the GitHub Release draft. It + publishes the selected wheel set to TestPyPI followed by PyPI. The release + owner publishes the GitHub Release draft in the announcement step. + +4. After completion, verify the final PyPI upload: ```bash pip install cuda-core==0.6.0 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 72fe9d76db7..e01e22e6ec4 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -52,23 +52,3 @@ updates: time: "09:00" timezone: "America/Los_Angeles" open-pull-requests-limit: 1 - - # GitHub Actions updates targeting the 12.9.x branch - - package-ecosystem: github-actions - directory: / - target-branch: "12.9.x" # keep in sync with backport_branch in ci/versions.yml - schedule: - interval: "monthly" - time: "09:00" - timezone: "America/Los_Angeles" - - # Keep churn down: only one open PR from this ecosystem at a time - open-pull-requests-limit: 1 - - groups: - actions-monthly: - applies-to: version-updates - patterns: ["*"] - update-types: ["major", "minor", "patch"] - - labels: [CI/CD, dependencies] diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index cb64af94faf..304d368b971 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -2,75 +2,84 @@ # # SPDX-License-Identifier: Apache-2.0 -name: "CI: Backport the merged PR" +name: "CI: Backport a merged PR to a release branch" on: - pull_request_target: - types: [closed, labeled] - branches: - - main workflow_dispatch: inputs: backport-branch: - description: "Branch to backport commits onto" - required: false + description: "Existing release branch to receive the fix" + required: true type: string pull-request: - description: "PR to backport" + description: "Merged PR to backport" required: true type: number - permissions: - contents: write # so it can comment - pull-requests: write # so it can create pull requests + contents: write + pull-requests: write + +concurrency: + group: backport-${{ inputs.pull-request }}-${{ inputs.backport-branch }} + cancel-in-progress: false jobs: - backport-from-pr: - name: Backport directly from a pull request - if: ${{ github.repository_owner == 'nvidia' && - github.event.pull_request.merged == true && - contains( github.event.pull_request.labels.*.name, 'to-be-backported') - }} + backport: + if: github.repository == 'NVIDIA/cuda-python' runs-on: ubuntu-latest steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Checkout workflow source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.sha }} - - name: Load branch name - id: get-branch + - name: Validate source PR and target branch + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + BACKPORT_BRANCH: ${{ inputs.backport-branch }} + PR_NUMBER: ${{ inputs.pull-request }} run: | - OLD_BRANCH=$(yq '.backport_branch' ci/versions.yml) - echo "OLD_BRANCH=${OLD_BRANCH}" >> $GITHUB_ENV + set -euo pipefail + if [[ ! "$PR_NUMBER" =~ ^[1-9][0-9]*$ ]]; then + echo "::error::The source PR must be a positive integer." + exit 1 + fi + if ! git check-ref-format "refs/heads/$BACKPORT_BRANCH"; then + echo "::error::Provide one exact target branch name." + exit 1 + fi + if [[ "$BACKPORT_BRANCH" == "$DEFAULT_BRANCH" ]]; then + echo "::error::Choose a release branch, not the default branch." + exit 1 + fi + if ! git ls-remote --exit-code --heads origin "refs/heads/$BACKPORT_BRANCH"; then + echo "::error::The target branch must already exist in this repository." + exit 1 + fi + if [[ "$(gh pr view "$PR_NUMBER" --repo "$GH_REPO" --json state --jq .state)" != MERGED ]]; then + echo "::error::The source PR must already be merged in this repository." + exit 1 + fi - - name: Create backport pull requests + # Workflow-file changes need a manual backport because GITHUB_TOKEN + # cannot push them. Generated changes need target-specific regeneration. + - name: Create backport pull request + id: backport uses: korthout/backport-action@8560fb503c275d433c56f05a2f64850093baa9f7 # v4.7.0 with: + source_pr_number: ${{ inputs.pull-request }} + target_branches: ${{ inputs.backport-branch }} + # The explicit target must not be combined with source PR labels. + label_pattern: '' copy_assignees: true - copy_labels_pattern: true + copy_labels_pattern: '^(?!to-be-backported$|backport ).*' copy_requested_reviewers: true - target_branches: ${{ env.OLD_BRANCH }} - backport-to-branch: - name: Backport a specific PR against a specific branch - if: github.repository_owner == 'nvidia' && github.event_name == 'workflow_dispatch' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Load branch from environment name - if: inputs.backport-branch == null + - name: Require successful backport + if: steps.backport.outputs.was_successful != 'true' run: | - BACKPORT_BRANCH=$(yq '.backport_branch' ci/versions.yml) - echo "BACKPORT_BRANCH=${BRANCH}" >> $GITHUB_ENV - - - name: Load branch name from input - if: inputs.backport-branch != null - run: echo "BACKPORT_BRANCH=${{ inputs.backport-branch }}" >> $GITHUB_ENV - - - name: Create backport pull requests - uses: korthout/backport-action@8560fb503c275d433c56f05a2f64850093baa9f7 # v4.7.0 - with: - copy_assignees: true - copy_labels_pattern: true - copy_requested_reviewers: true - target_branches: ${{ env.BACKPORT_BRANCH }} - source_pr_number: ${{ inputs.pull-request }} + echo "::error::Backport failed; resolve the conflict or prepare the target-specific fix manually." + exit 1 diff --git a/AGENTS.md b/AGENTS.md index 176dc1f84e4..ac6a567ea8d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,6 +40,29 @@ inputs, CI selection, or release routing. enforce their byte-for-byte invariants. Semantic differences elsewhere do not relax those requirements. +## Synchronized code blocks + +Use matching `BEGIN SYNCED ` and `END SYNCED ` comments for +deliberately duplicated snippets whose contents must remain byte-for-byte +identical. The group name identifies all copies; the boundaries define the +shared snippet, not the surrounding file. + +- Before editing a marked block, search from the repository root for its exact + `BEGIN SYNCED ` marker, for example with `rg -n -F`. Read every copy + and update them together, including copies outside the current package. +- Compare the complete marked blocks after editing. Also check required + imports and surrounding assumptions, such as relative directory depth, + which may live outside the markers. +- During review, identify groups touched by the diff and compare every copy, + including files absent from the diff. Use the base revision too when markers + were removed or renamed. Report drift, missing boundaries, and newly copied + snippets that omit the markers as review findings. +- Preserve both markers when copying a snippet. If a copy must diverge, + explain why and explicitly revise the group membership; do not remove or + rename a marker merely to conceal drift. +- In the work or review summary, name the groups and files compared, or state + why verification could not be completed. + # Git-derived version lifecycle Package versions are derived from reachable Git tags by `setuptools-scm`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d91e9482412..cf19721c6d3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,9 +37,8 @@ Thank you for your interest in contributing to CUDA Python! Based on the type of - [Developer Certificate of Origin (DCO)](#developer-certificate-of-origin-dco) - [CI infrastructure overview](#ci-infrastructure-overview) - [CI Pipeline Flow](#ci-pipeline-flow) - - [Pipeline Execution Details](#pipeline-execution-details) - - [Source and Artifact Flow](#source-and-artifact-flow) - - [Key Infrastructure Details](#key-infrastructure-details) + - [CUDA-major Artifact Flow](#cuda-major-artifact-flow) + - [Release Branches](#release-branches) - [Code coverage](#code-coverage) @@ -426,36 +425,37 @@ The CUDA Python project uses a comprehensive CI pipeline that builds, tests, and The CI pipeline diagram is maintained as Mermaid source in [`ci/ci-pipeline.mmd`](ci/ci-pipeline.mmd). -### Pipeline Execution Details - -**Parallel Execution**: The CI pipeline leverages parallel execution to optimize build and test times: -- **Build Stage**: Different architectures/operating systems (linux-64, linux-aarch64, win-64) are built in parallel across their respective runners -- **Test Stage**: Different architectures/operating systems/CUDA versions are tested in parallel; documentation preview is also built in parallel with testing - -### Source and Artifact Flow - -- Pushes to `main` build and test both registered bindings lines and their - dependent packages from the same source revision. -- Pull requests build affected packages and test their consumers. Unchanged - wheels and test artifacts can reuse a successful exact-baseline CI run; - without a complete usable baseline, CI builds and tests everything. -- Bindings tags select their matching bindings root and metapackage, using - published Pathfinder. They do not require a Core release. -- Other branches retain their own release procedure and compatible tooling. - Main-tree CI no longer fetches CUDA 12 bindings artifacts from `12.9.x`. - -See [Reading CI Jobs and Summaries](ci/README.md#reading-ci-jobs-and-summaries) -for package/major names, local versus published bindings, and reuse details. - -### Key Infrastructure Details - -- **Self-hosted runners**: Used for Linux builds and GPU testing (more resources, faster builds) -- **GitHub-hosted runners**: Used for Windows builds and general tasks -- **Artifact retention**: Set per workflow for wheels, documentation, and test results -- **Cache retention**: GitHub Cache for build dependencies and environments -- **Security**: All commits must be signed, untrusted code blocked -- **Parallel execution**: Matrix builds across Python versions and platforms -- **Component isolation**: Each component (core, bindings, pathfinder, python) can be built/released independently +The [CI workflow](.github/workflows/ci.yml) defines the supported platform, +Python, and CUDA matrices. Build and test jobs run in parallel across their +configured runners. Package selection and artifact validation are shared +through the [CI tools](ci/README.md). + +### CUDA-major Artifact Flow + +- CUDA 12.9 bindings live in `cuda_bindings_12/`; CUDA 13 bindings live in + `cuda_bindings_13/`. The registry assigns their maintenance and current roles. +- Development CI builds changed roots and affected dependents, reusing a + validated baseline for unaffected roots. Shared changes and scheduled runs + cover both CUDA majors. +- A bindings tag selects one line's bindings and metapackage. Its release + validation uses published Pathfinder and does not require a CUDA Core or + other-major release. +- Artifacts identify their Python version, toolkit, platform, and source SHA + where applicable. Release workflows require the exact tag's successful CI. + +### Release Branches + +`main` integrates changes for both supported majors. Short release branches +can stabilize a selected release or carry urgent fixes while development +continues. Return applicable fixes to `main` and assess both source roots. +The historical `12.9.x` branch stays frozen except for emergency fixes, +which must be reconciled into `main`. New main CI and releases do not fetch +package artifacts from that branch. + +The [bindings release guide](.github/RELEASE-bindings.md) covers release scope, +manual backport automation, source and control revisions, and validation. +The [CUDA 12 maintenance guide](cuda_bindings_12/MAINTENANCE.md) links the +shared regeneration and cross-root review policy. ## Code coverage diff --git a/ci/README.md b/ci/README.md index bb313fcc895..5cc0eb09f0f 100644 --- a/ci/README.md +++ b/ci/README.md @@ -429,3 +429,66 @@ deploy the documentation to that preview branch. Run once per component when validating more than one package; use `component=cuda-python` for the matching metapackage documentation. Other historical release lines likewise need tooling compatible with their tagged layout. + +## Maintaining Both Bindings Roots + +`main` is the integration branch for both bindings release lines. The old +`12.9.x` branch stays frozen except for emergency fixes using compatible +historical tooling; reconcile any such fix into `cuda_bindings_12/` on `main`. +Routine CUDA 12 development belongs in that main-tree root. Short release +branches may stabilize a selected version or carry urgent fixes while `main` advances. +The [bindings release guide](../.github/RELEASE-bindings.md) describes branch +creation, backport automation, independent release validation, and returning +fixes to `main`. The +[CUDA 12 maintenance guide](../cuda_bindings_12/MAINTENANCE.md) identifies the +maintenance root. + +For generated bindings, change cybind first and regenerate each affected +package root against its intended toolkit inputs. Review the generated diff, +record the cybind revision, toolkit inputs, and command in the pull request, +and check modified files with +`python toolshed/check_generated_file_seals.py `. The seal verifies +the content of an individual generated file; it does not identify the cybind +revision or prove that the two roots should have identical output. Generated +output may legitimately differ across toolkit targets. + +For a handwritten bindings fix, inspect the corresponding code in the other +root. In the pull request, identify the matching change or explain concretely +why the fix does not apply there. A reviewer must verify that judgment: there +is no general deterministic check for semantic equivalence of handwritten +code across the two roots. Where files are intentionally identical, a narrowly +scoped byte-for-byte check can be added after establishing that invariant. + +Major-line maintenance can include deliberately selected compatibility work +such as a new Python version or a new API supported by that toolkit. A frozen +patch release has a narrower scope: fixes and release prerequisites approved +for that release. State which policy applies in the release checklist and +notes; a maintenance label alone does not promise a fixes-only release. + +Keep generator development and continuous toolkit qualification independent +of this source layout. A cybind change should be exercised against both +supported consumers before its generated output is imported. Record the +generator revision and toolkit inputs for each import, including any manual +post-generation adjustment. File seals establish content integrity, not +generation provenance. Moving QA directories or redesigning cybind asset +storage is not required to maintain both roots here. + +## Changing Supported Release Lines + +When support moves from CUDA 12/13 to CUDA 13/14, retain `cuda_bindings_13/` +as the maintenance source and introduce a distinct CUDA 14 root. Then: + +1. Update `ci/versions.yml`: remove the retired CUDA 12 root, mark the CUDA + 13 root `maintenance`, mark the CUDA 14 root `current`, and set each exact + toolkit build/test version. +2. Align each root's `pyproject.toml` `git_describe_command --match` selector + and any preview bootstrap target with its release family. Update per-root packaging, + pixi environments, documentation, and dependent package constraints for the + supported lines. +3. Build and test both roots and their dependent packages on the supported + platforms. Validate release selection and run publication-incapable dry + runs for tags from each line before releasing from the new layout. + +The same branch policy applies after the rollover: `main` integrates the +current and maintenance roots, short release branches stabilize releases, +and retired release branches are retained for history. diff --git a/ci/tools/bindings_config.py b/ci/tools/bindings_config.py index c333eedb1ed..cbd662e2d7e 100644 --- a/ci/tools/bindings_config.py +++ b/ci/tools/bindings_config.py @@ -145,6 +145,7 @@ def parse_config(raw: Mapping[str, Any]) -> BindingsConfig: ) if len({package.toolkit[0] for package in packages}) != len(packages): raise ValueError("CUDA bindings cuda_major values must be unique") + # Older schema-2 tags may still record the retired workflow branch. if "backport_branch" in raw: maintenance = next(package for package in packages if package.release_status == "maintenance") expected_branch = f"{maintenance.ctk_target}.x" diff --git a/ci/versions.yml b/ci/versions.yml index c4df0886e71..83872f62b08 100644 --- a/ci/versions.yml +++ b/ci/versions.yml @@ -3,9 +3,6 @@ schema_version: 2 -# Retain until the legacy release and backport workflows stop reading this field. -backport_branch: "12.9.x" # keep in sync with target-branch in .github/dependabot.yml - cuda: bindings: package_roots: diff --git a/cuda_bindings_12/AGENTS.md b/cuda_bindings_12/AGENTS.md index 037dda8f84a..931d0ab4e45 100644 --- a/cuda_bindings_12/AGENTS.md +++ b/cuda_bindings_12/AGENTS.md @@ -7,6 +7,10 @@ Inspect the CUDA 13 counterpart during implementation and review, and record matching changes or why they are not applicable. Preserve intentional API, layout, and build differences rather than copying the CUDA 13 root wholesale. +Follow the [maintenance guide](MAINTENANCE.md) for branch and release policy +and [Maintaining Both Bindings Roots](../ci/README.md#maintaining-both-bindings-roots) +for generation provenance and review expectations. + ## Generated and handwritten sources - Files carrying a `CYTHON-BINDINGS-GENERATED` seal are cybind output, diff --git a/cuda_bindings_12/MAINTENANCE.md b/cuda_bindings_12/MAINTENANCE.md new file mode 100644 index 00000000000..dc565132e8e --- /dev/null +++ b/cuda_bindings_12/MAINTENANCE.md @@ -0,0 +1,23 @@ + + +# Maintaining the CUDA 12 bindings line + +`cuda_bindings_12/` is the CUDA 12.9 maintenance package root. The current +CUDA 13 bindings live in `cuda_bindings_13/`. The package roots and their release +statuses are configured in [`ci/versions.yml`](../ci/versions.yml). + +Integrate both release lines on `main`. The former `12.9.x` branch stays +frozen except for emergency fixes using compatible historical tooling; +reconcile those fixes into `cuda_bindings_12/`. Routine CUDA 12 fixes, tests, +and documentation belong in this main-tree root. Short release branches may +stabilize a release or carry an urgent fix; reconcile such fixes into `main` +and assess the CUDA 13 root too. + +Follow the [bindings release guide](../.github/RELEASE-bindings.md) for branch +selection, patch-release scope, backports, and release validation. + +Follow the [shared regeneration and review policy](../ci/README.md#maintaining-both-bindings-roots) +when changing implementation in either package root. diff --git a/cuda_bindings_12/README.md b/cuda_bindings_12/README.md index 931b601f49a..9748a83c410 100644 --- a/cuda_bindings_12/README.md +++ b/cuda_bindings_12/README.md @@ -11,7 +11,9 @@ Please refer to the [Installation page](https://nvidia.github.io/cuda-python/cud ## Developing -This subpackage adheres to the developing practices described in the parent metapackage [CONTRIBUTING.md](https://github.com/NVIDIA/cuda-python/blob/main/CONTRIBUTING.md). +This is the CUDA 12.9 maintenance source root. Follow the repository +[contribution guide](../CONTRIBUTING.md) and the +[maintenance guide](MAINTENANCE.md) for source builds and cross-major changes. ## Testing @@ -39,7 +41,7 @@ To run these tests: Cython tests are located in `tests/cython` and need to be built. These builds have the same CUDA Toolkit header requirements as [Installing from Source](https://nvidia.github.io/cuda-python/cuda-bindings/12.9.7/install.html#requirements) where the major.minor version must match `cuda.bindings`. To build them: 1. Setup environment variable `CUDA_HOME` with the path to the CUDA Toolkit installation. -2. Run `build_tests` script located in `test/cython` appropriate to your platform. This will both cythonize the tests and build them. +2. Run the `build_tests` script located in `tests/cython` appropriate to your platform. This will both cythonize the tests and build them. To run these tests: * `python -m pytest tests/cython/` against editable installations @@ -60,10 +62,12 @@ In addition, extra examples are included: wrappers of the driver API. To run these samples: -* `python -m pytest tests/cython/` against editable installations -* `pytest tests/cython/` against installed packages +* `python -m pytest examples/` against editable installations +* `pytest examples/` against installed packages ### Benchmark See the shared [cuda.bindings benchmark harness](../benchmarks/cuda_bindings/README.md) -for performance benchmarks and usage instructions. +for performance benchmarks and usage instructions. Its configured environments +currently target CUDA 13; benchmarking CUDA 12 requires a compatible environment +configured separately. diff --git a/cuda_bindings_12/docs/README.md b/cuda_bindings_12/docs/README.md index 9465dcedf39..b533f56e349 100644 --- a/cuda_bindings_12/docs/README.md +++ b/cuda_bindings_12/docs/README.md @@ -16,7 +16,7 @@ To document APIs changed in the checkout, install the matching source build in your documentation environment before running `./build_docs.sh`. `build/html/latest` is for local preview only. Follow the selected branch's -release procedure for publication. Maintenance publication must exclude `latest` +[bindings release guide](../../.github/RELEASE-bindings.md) for publication. Maintenance publication must exclude `latest` and the shared version-selector files so it cannot overwrite the current-major site. Keep older versioned pages intact; do not publish the entire local build directory over the shared site. diff --git a/cuda_core/AGENTS.md b/cuda_core/AGENTS.md index 8b3549a26f0..b4b8f2b53af 100644 --- a/cuda_core/AGENTS.md +++ b/cuda_core/AGENTS.md @@ -26,8 +26,8 @@ This file describes `cuda_core`, the high-level Pythonic CUDA subpackage in the dependency wiring. Logic shared with `cuda-bindings` (toolchain selection, the compiler flag set, the Cython cache helpers and the rebuild stamps) lives in `_build_shared.py`. `cuda_bindings_13/_build_shared.py` is canonical; - `cuda_core/_build_shared.py` must be either a symlink to it or a byte-for-byte - identical copy. + each package-local `_build_shared.py` must be a symlink to it or a byte-for-byte + identical copy, including maintenance bindings roots. ## Build and version coupling diff --git a/cuda_python/AGENTS.md b/cuda_python/AGENTS.md index 1bf20fca3dc..e86d0af29dd 100644 --- a/cuda_python/AGENTS.md +++ b/cuda_python/AGENTS.md @@ -28,11 +28,12 @@ monorepo. ## Release coupling -- For the current-major metapackage, `setup.py` pins `cuda-core` to a minor series (`cuda-core~=X.Y.0`). Every - `cuda-core` release must bump that pin, and a `cuda-python` release should - follow right after, so that `pip install cuda-python` resolves to the new - `cuda-core`. The `cuda-core` release checklist (`.github/RELEASE-core.md`) - has this step. +- The current-major metapackage in `setup.py` pins `cuda-core` to a minor + series (`cuda-core~=X.Y.0`). The CUDA 12 metapackage depends only on bindings. + Every `cuda-core` release must bump that pin, and a `cuda-python` release + for the current major should follow right after, so that + `pip install cuda-python` resolves to the new `cuda-core`. The `cuda-core` + release checklist (`.github/RELEASE-core.md`) has this step. - Users should pin `cuda-python` alone. A separate `cuda-core` pin next to it can make the install unresolvable after a `cuda-core` release. - If you update docs structure, ensure `docs/build_all_docs.sh` still collects