Skip to content

Commit 57a538c

Browse files
leofangclaude
andauthored
cuda.core: consolidate driver version query functions (#2040)
* cuda.core: consolidate get_driver_version and get_driver_version_full Merge the two separate driver version query functions into a single get_driver_version() that returns (umd_version, kmd_version) — a pair of version tuples. UMD is a 2-tuple (major, minor) and KMD is a 3-tuple (major, minor, patch). The function now requires NVML. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Remove unused driver import from _system.pyx Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix KMD version test to allow 2-tuple on WSL Windows driver version strings only have two components, so nvmlSystemGetDriverVersion returns X.Y on WSL instead of X.Y.Z. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Split into get_user_mode_driver_version and get_kernel_mode_driver_version Per review feedback, split the consolidated get_driver_version() into two separate functions so each returns a simple tuple[int, ...]: - get_user_mode_driver_version(): works with or without NVML (falls back to cuDriverGetVersion), returns (major, minor) - get_kernel_mode_driver_version(): requires NVML, returns (major, minor, patch) or (major, minor) on WSL Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add example version strings to driver version docstrings Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Remove NVML implementation detail from UMD docstring Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Sort __all__ alphabetically in system/__init__.py Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a61cb05 commit 57a538c

5 files changed

Lines changed: 64 additions & 65 deletions

File tree

cuda_core/cuda/core/system/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111

1212
__all__ = [
1313
"CUDA_BINDINGS_NVML_IS_COMPATIBLE",
14-
"get_driver_version",
15-
"get_driver_version_full",
14+
"get_kernel_mode_driver_version",
1615
"get_num_devices",
1716
"get_process_name",
17+
"get_user_mode_driver_version",
1818
]
1919

2020

cuda_core/cuda/core/system/_system.pyx

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,52 +29,48 @@ else:
2929
from cuda.core._utils.cuda_utils import driver, handle_return, runtime
3030

3131

32-
def get_driver_version(kernel_mode: bool = False) -> tuple[int, int]:
32+
def get_user_mode_driver_version() -> tuple[int, ...]:
3333
"""
34-
Get the driver version.
34+
Get the user-mode (UMD / CUDA) driver version.
3535

36-
Parameters
37-
----------
38-
kernel_mode: bool
39-
When `True`, return the kernel-mode driver version, e.g. 580.65.06.
40-
Otherwise, return the user-mode driver version, e.g. 13.0.1.
36+
This is the most commonly needed version when checking CUDA driver
37+
compatibility. It works with all ``cuda-bindings`` versions.
4138

4239
Returns
4340
-------
44-
version: tuple[int, int]
45-
Tuple in the format `(MAJOR, MINOR)`.
41+
version : tuple[int, ...]
42+
A 2-tuple ``(MAJOR, MINOR)``, e.g. ``(13, 0)`` for CUDA 13.0.
4643
"""
47-
return get_driver_version_full(kernel_mode)[:2]
44+
cdef int v
45+
if CUDA_BINDINGS_NVML_IS_COMPATIBLE:
46+
initialize()
47+
v = nvml.system_get_cuda_driver_version()
48+
else:
49+
v = handle_return(driver.cuDriverGetVersion())
50+
return (v // 1000, (v // 10) % 100)
4851

4952

50-
def get_driver_version_full(kernel_mode: bool = False) -> tuple[int, int, int]:
53+
def get_kernel_mode_driver_version() -> tuple[int, ...]:
5154
"""
52-
Get the full driver version.
53-
54-
Parameters
55-
----------
56-
kernel_mode: bool
57-
When `True`, return the kernel-mode driver version, e.g. 580.65.06.
58-
Otherwise, return the user-mode driver version, e.g. 13.0.1.
55+
Get the kernel-mode (KMD / GPU) driver version, e.g. 580.65.06.
5956

6057
Returns
6158
-------
62-
version: tuple[int, int, int]
63-
Tuple in the format `(MAJOR, MINOR, PATCH)`.
59+
version : tuple[int, ...]
60+
Typically a 3-tuple ``(MAJOR, MINOR, PATCH)``
61+
(2-tuple on WSL), e.g. ``(580, 65, 6)``.
62+
63+
Raises
64+
------
65+
RuntimeError
66+
If the NVML library is not available.
6467
"""
65-
cdef int v
66-
if kernel_mode:
67-
if not CUDA_BINDINGS_NVML_IS_COMPATIBLE:
68-
raise ValueError("Kernel-mode driver version requires NVML support")
69-
initialize()
70-
return tuple(int(v) for v in nvml.system_get_driver_version().split("."))
71-
else:
72-
if CUDA_BINDINGS_NVML_IS_COMPATIBLE:
73-
initialize()
74-
v = nvml.system_get_cuda_driver_version()
75-
else:
76-
v = handle_return(driver.cuDriverGetVersion())
77-
return (v // 1000, (v // 10) % 100, v % 10)
68+
if not CUDA_BINDINGS_NVML_IS_COMPATIBLE:
69+
raise RuntimeError(
70+
"get_kernel_mode_driver_version requires NVML support"
71+
)
72+
initialize()
73+
return tuple(int(x) for x in nvml.system_get_driver_version().split("."))
7874

7975

8076
def get_nvml_version() -> tuple[int, ...]:
@@ -137,8 +133,8 @@ def get_process_name(pid: int) -> str:
137133

138134
__all__ = [
139135
"get_driver_branch",
140-
"get_driver_version",
141-
"get_driver_version_full",
136+
"get_kernel_mode_driver_version",
137+
"get_user_mode_driver_version",
142138
"get_nvml_version",
143139
"get_num_devices",
144140
"get_process_name",

cuda_core/docs/source/api.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ Basic functions
274274
.. autosummary::
275275
:toctree: generated/
276276

277-
system.get_driver_version
278-
system.get_driver_version_full
277+
system.get_user_mode_driver_version
278+
system.get_kernel_mode_driver_version
279279
system.get_driver_branch
280280
system.get_num_devices
281281
system.get_nvml_version

cuda_core/docs/source/release/1.0.0-notes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ Breaking changes
163163
:mod:`cuda.core.utils` module.
164164
(`#2028 <https://github.com/NVIDIA/cuda-python/issues/2028>`__)
165165

166+
- Replaced ``system.get_driver_version()`` and
167+
``system.get_driver_version_full()`` with
168+
:func:`system.get_user_mode_driver_version` (works with or without
169+
NVML) and :func:`system.get_kernel_mode_driver_version` (requires
170+
NVML). Each returns a ``tuple[int, ...]``.
171+
166172
Fixes and enhancements
167173
-----------------------
168174

cuda_core/tests/system/test_system_system.py

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,25 @@
1919
from .conftest import skip_if_nvml_unsupported
2020

2121

22-
def test_driver_version():
23-
driver_version = system.get_driver_version()
22+
def test_user_mode_driver_version():
23+
umd = system.get_user_mode_driver_version()
24+
assert isinstance(umd, tuple)
25+
assert len(umd) == 2
2426
version = handle_return(driver.cuDriverGetVersion())
25-
expected_driver_version = (version // 1000, (version % 1000) // 10)
26-
assert driver_version == expected_driver_version, "Driver version does not match expected value"
27+
expected = (version // 1000, (version % 1000) // 10)
28+
assert umd == expected, "UMD driver version does not match expected value"
29+
30+
31+
@skip_if_nvml_unsupported
32+
def test_kernel_mode_driver_version():
33+
kmd = system.get_kernel_mode_driver_version()
34+
assert isinstance(kmd, tuple)
35+
assert len(kmd) in (2, 3)
36+
ver_maj, ver_min, *ver_patch = kmd
37+
assert 400 <= ver_maj < 1000
38+
assert ver_min >= 0
39+
if ver_patch:
40+
assert 0 <= ver_patch[0] <= 99
2741

2842

2943
def test_num_devices():
@@ -41,28 +55,11 @@ def test_devices():
4155
assert device.device_id == expected_device.device_id, "Device ID does not match expected value"
4256

4357

44-
def test_cuda_driver_version():
45-
cuda_driver_version = system.get_driver_version_full()
46-
assert isinstance(cuda_driver_version, tuple)
47-
assert len(cuda_driver_version) == 3
48-
49-
ver_maj, ver_min, ver_patch = cuda_driver_version
50-
assert ver_maj >= 10
51-
assert 0 <= ver_min <= 99
52-
assert 0 <= ver_patch <= 9
53-
54-
55-
@skip_if_nvml_unsupported
56-
def test_gpu_driver_version():
57-
driver_version = system.get_driver_version(kernel_mode=True)
58-
assert isinstance(driver_version, tuple)
59-
assert len(driver_version) in (2, 3)
60-
61-
(ver_maj, ver_min, *ver_patch) = driver_version
62-
assert 400 <= ver_maj < 1000
63-
assert ver_min >= 0
64-
if ver_patch:
65-
assert 0 <= ver_patch[0] <= 99
58+
def test_kernel_mode_driver_version_requires_nvml():
59+
if system.CUDA_BINDINGS_NVML_IS_COMPATIBLE:
60+
pytest.skip("NVML is available, cannot test the error path")
61+
with pytest.raises(RuntimeError, match="requires NVML support"):
62+
system.get_kernel_mode_driver_version()
6663

6764

6865
@skip_if_nvml_unsupported

0 commit comments

Comments
 (0)