-
Notifications
You must be signed in to change notification settings - Fork 331
cuda.core: require a cuda-bindings floor and call the driver through its resolved pointers (#2783) #2920
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Andy-Jost
wants to merge
17
commits into
NVIDIA:main
Choose a base branch
from
Andy-Jost:ajost/core-bindings-runtime-floor
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+3,481
−2,865
Open
cuda.core: require a cuda-bindings floor and call the driver through its resolved pointers (#2783) #2920
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
7fc73b3
cuda.core: require a per-major cuda-bindings floor at build and run time
Andy-Jost f4757aa
cuda.core: fence C++ on the CUDA major only, never on CUDA_VERSION
Andy-Jost b9ada0d
cuda.core: call the driver through cuda-bindings' resolved pointers (…
Andy-Jost 4955393
cuda.core: gate features on the driver alone now that cuda-bindings h…
Andy-Jost 65c63b0
cuda.core tests: gate the checkpoint helper tests on the CUDA 13 buil…
Andy-Jost cd1c42d
Merge remote-tracking branch 'origin/main' into ajost/core-bindings-r…
Andy-Jost af88337
cuda.core: regenerate stubs and drop exec from the floor tool and tes…
Andy-Jost b4fedec
cuda.core: import cuda.bindings for the build check through the #1824…
Andy-Jost b000b54
Merge remote-tracking branch 'origin/main' into ajost/core-bindings-r…
Andy-Jost b06cc7c
cuda.core: read linked LTOIR through cynvjitlink instead of probing t…
Andy-Jost ab980a9
cuda.core: declare the cuda-bindings floor once, in the pyproject ext…
Andy-Jost 18c5a34
cuda.core: compare headers, not version strings, in the cuda-bindings…
Andy-Jost 194f9ea
cuda.core: latch a failed driver-table fill, keep pending exceptions,…
Andy-Jost a37c10a
cuda.core: keep the NVML constant's stub annotation-only; finish the …
Andy-Jost 6ba9004
cuda-bindings header check at build; final floor messages; bounds spe…
Andy-Jost b6cbcc0
Copyedit the docs, comments, docstrings and messages this PR adds (#2…
Andy-Jost 1f05f42
Merge remote-tracking branch 'origin/main' into ajost/core-bindings-r…
Andy-Jost File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| #!/usr/bin/env python3 | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """Print the cuda-bindings floor of a cuda-core wheel for one CUDA major. | ||
|
|
||
| cuda_core_bindings_floor.py --wheel dist/cuda_core-*.whl --major 13 | ||
| -> 13.4.1 | ||
|
|
||
| CI installs `cuda-bindings==<floor>` next to a freshly built cuda-core wheel to | ||
| test the oldest cuda-bindings that wheel supports (BINDINGS_SOURCE=floor in | ||
| ci/tools/env-vars). This script reads the floor from the wheel under test, not | ||
| from the checkout, so a nightly job that tests a wheel built from another | ||
| commit reads that wheel's floor. | ||
|
|
||
| Each build records its floor in the generated cuda/core/_build_info.py. A | ||
| single-major build places the file at top level. The merged wheel places it | ||
| under cuda/core/cu<major>/. This script parses the CUDA_BINDINGS_FLOOR literal | ||
| out of it and never runs it. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import argparse | ||
| import ast | ||
| import sys | ||
| import zipfile | ||
| from pathlib import Path | ||
|
|
||
| MODULE = "_build_info.py" | ||
|
|
||
|
|
||
| def _literal(source: str, name: str): | ||
| """The literal that `source` assigns to `name` at module level. Parses the source and never runs it.""" | ||
| for node in ast.parse(source, MODULE).body: | ||
| if isinstance(node, ast.AnnAssign): | ||
| targets = [node.target] | ||
| elif isinstance(node, ast.Assign): | ||
| targets = node.targets | ||
| else: | ||
| continue | ||
| if node.value is not None and any(isinstance(t, ast.Name) and t.id == name for t in targets): | ||
| return ast.literal_eval(node.value) | ||
| raise SystemExit(f"{MODULE} does not assign {name}") | ||
|
|
||
|
|
||
| def floor_from_source(source: str, major: int) -> str: | ||
| if _literal(source, "CUDA_MAJOR") != major: | ||
| raise SystemExit(f"{MODULE} records a CUDA {_literal(source, 'CUDA_MAJOR')} build, not CUDA {major}") | ||
| return ".".join(str(part) for part in _literal(source, "CUDA_BINDINGS_FLOOR")) | ||
|
|
||
|
|
||
| def floor_from_wheel(wheel: Path, major: int) -> str: | ||
| with zipfile.ZipFile(wheel) as zf: | ||
| names = set(zf.namelist()) | ||
| for candidate in (f"cuda/core/cu{major}/{MODULE}", f"cuda/core/{MODULE}"): | ||
| if candidate in names: | ||
| return floor_from_source(zf.read(candidate).decode("utf-8"), major) | ||
| raise SystemExit(f"{wheel.name} contains no build for CUDA {major}: it has no {MODULE}. Is it a cuda-core wheel?") | ||
|
|
||
|
|
||
| def main(argv: list[str] | None = None) -> int: | ||
| parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) | ||
| parser.add_argument("--wheel", type=Path, required=True, help="the cuda-core wheel under test") | ||
| parser.add_argument("--major", type=int, required=True, help="CUDA major series (12 or 13)") | ||
| args = parser.parse_args(argv) | ||
| print(floor_from_wheel(args.wheel, args.major)) | ||
| return 0 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| sys.exit(main()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| import importlib.util | ||
| import zipfile | ||
| from pathlib import Path | ||
|
|
||
| import pytest | ||
|
|
||
| TOOLS = Path(__file__).resolve().parent.parent | ||
|
|
||
|
|
||
| def _load(name, path): | ||
| spec = importlib.util.spec_from_file_location(name, path) | ||
| module = importlib.util.module_from_spec(spec) | ||
| spec.loader.exec_module(module) | ||
| return module | ||
|
|
||
|
|
||
| tool = _load("cuda_core_bindings_floor", TOOLS / "cuda_core_bindings_floor.py") | ||
|
|
||
| FLOORS = {12: (12, 9, 8), 13: (13, 4, 1)} | ||
|
|
||
|
|
||
| def _build_info(major): | ||
| floor = FLOORS[major] | ||
| return ( | ||
| "# Generated by build_hooks.py at build time. Do not edit or commit.\n" | ||
| f"CUDA_MAJOR = {major}\n" | ||
| f"CUDA_VERSION = {major * 1000 + floor[1] * 10} # the cuda.h this build compiled against\n" | ||
| f"CUDA_BINDINGS_FLOOR = {floor!r}\n" | ||
| f"CUDA_BINDINGS_BUILD_VERSION = '{major}.{floor[1]}.{floor[2]}'\n" | ||
| ) | ||
|
|
||
|
|
||
| def _wheel(tmp_path, entries): | ||
| path = tmp_path / "cuda_core-1.3.0-cp312-cp312-linux_x86_64.whl" | ||
| with zipfile.ZipFile(path, "w") as zf: | ||
| for name, major in entries.items(): | ||
| zf.writestr(name, _build_info(major)) | ||
| return path | ||
|
|
||
|
|
||
| @pytest.mark.agent_authored(model="claude-fable-5-1") | ||
| @pytest.mark.parametrize("major", [12, 13]) | ||
| def test_reads_the_merged_wheel_layout(tmp_path, major): | ||
| wheel = _wheel(tmp_path, {"cuda/core/cu12/_build_info.py": 12, "cuda/core/cu13/_build_info.py": 13}) | ||
| assert tool.floor_from_wheel(wheel, major) == ".".join(map(str, FLOORS[major])) | ||
|
|
||
|
|
||
| @pytest.mark.agent_authored(model="claude-fable-5-1") | ||
| def test_reads_a_single_major_wheel(tmp_path): | ||
| wheel = _wheel(tmp_path, {"cuda/core/_build_info.py": 13}) | ||
| assert tool.floor_from_wheel(wheel, 13) == "13.4.1" | ||
|
|
||
|
|
||
| @pytest.mark.agent_authored(model="claude-fable-5-1") | ||
| def test_rejects_a_single_major_wheel_of_another_major(tmp_path): | ||
| wheel = _wheel(tmp_path, {"cuda/core/_build_info.py": 13}) | ||
| with pytest.raises(SystemExit, match="records a CUDA 13 build, not CUDA 12"): | ||
| tool.floor_from_wheel(wheel, 12) | ||
|
|
||
|
|
||
| @pytest.mark.agent_authored(model="claude-fable-5-1") | ||
| def test_rejects_a_wheel_without_the_build_record(tmp_path): | ||
| wheel = _wheel(tmp_path, {}) | ||
| with pytest.raises(SystemExit, match="contains no build for CUDA 13"): | ||
| tool.floor_from_wheel(wheel, 13) | ||
|
|
||
|
|
||
| @pytest.mark.agent_authored(model="claude-fable-5-1") | ||
| def test_rejects_a_build_record_without_the_floor(): | ||
| with pytest.raises(SystemExit, match="does not assign CUDA_BINDINGS_FLOOR"): | ||
| tool.floor_from_source("CUDA_MAJOR = 13\n", 13) | ||
|
|
||
|
|
||
| @pytest.mark.agent_authored(model="claude-fable-5-1") | ||
| def test_cli_prints_the_floor(tmp_path, capsys): | ||
| wheel = _wheel(tmp_path, {"cuda/core/_build_info.py": 13}) | ||
| assert tool.main(["--wheel", str(wheel), "--major", "13"]) == 0 | ||
| assert capsys.readouterr().out.strip() == "13.4.1" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Main concern: "supports" seems a tad too strong, e.g. I'd want to stay clear of leading someone to think that we're somehow supporting features added in toolkits with a minor version newer than the cuda-bindings minor version.
Minor concern: make "this cuda-bindings build" specific.