Coverage for cuda / pathfinder / _utils / driver_info.py: 100.00%

34 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-29 01:27 +0000

1# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 

2# SPDX-License-Identifier: Apache-2.0 

3 

4from __future__ import annotations 

5 

6import ctypes 

7import functools 

8from collections.abc import Callable 

9from dataclasses import dataclass 

10 

11from cuda.pathfinder._dynamic_libs.load_nvidia_dynamic_lib import ( 

12 load_nvidia_dynamic_lib as _load_nvidia_dynamic_lib, 

13) 

14from cuda.pathfinder._utils.platform_aware import IS_WINDOWS 

15 

16 

17class QueryDriverCudaVersionError(RuntimeError): 

18 """Raised when ``query_driver_cuda_version()`` cannot determine the CUDA driver version.""" 

19 

20 

21@dataclass(frozen=True, slots=True) 

22class DriverCudaVersion: 

23 """ 

24 CUDA-facing driver version reported by ``cuDriverGetVersion()``. 

25 

26 The name ``DriverCudaVersion`` is intentionally specific: this dataclass 

27 models the version shown as ``CUDA Version`` in ``nvidia-smi``, not the 

28 graphics driver release shown as ``Driver Version``. More specifically, 

29 it reflects the CUDA user-mode driver (UMD) interface version reported by 

30 ``cuDriverGetVersion()``, not the kernel-mode driver (KMD) package 

31 version. 

32 

33 Example ``nvidia-smi`` output:: 

34 

35 +---------------------------------------------------------------------+ 

36 | NVIDIA-SMI 595.58.03 Driver Version: 595.58.03 CUDA Version: 13.2 | 

37 +---------------------------------------------------------------------+ 

38 

39 For the example above, ``DriverCudaVersion(encoded=13020, major=13, 

40 minor=2)`` corresponds to ``CUDA Version: 13.2``. It does not correspond 

41 to ``Driver Version: 595.58.03``. 

42 """ 

43 

44 encoded: int 

45 major: int 

46 minor: int 

47 

48 

49@functools.cache 

50def query_driver_cuda_version() -> DriverCudaVersion: 

51 """Return the CUDA driver version parsed into its major/minor components.""" 

52 try: 1bfe

53 encoded = _query_driver_cuda_version_int() 1bfe

54 return DriverCudaVersion( 1bf

55 encoded=encoded, 

56 major=encoded // 1000, 

57 minor=(encoded % 1000) // 10, 

58 ) 

59 except Exception as exc: 1e

60 raise QueryDriverCudaVersionError("Failed to query the CUDA driver version.") from exc 1e

61 

62 

63def _query_driver_cuda_version_int() -> int: 

64 """Return the encoded CUDA driver version from ``cuDriverGetVersion()``.""" 

65 loaded_cuda = _load_nvidia_dynamic_lib("cuda") 1bcd

66 if IS_WINDOWS: 1bcd

67 # `ctypes.WinDLL` exists on Windows at runtime. The ignore is only for 

68 # Linux mypy runs, where the platform stubs do not define that attribute. 

69 loader_cls: Callable[[str], ctypes.CDLL] = ctypes.WinDLL # type: ignore[attr-defined] 1bd

70 else: 

71 loader_cls = ctypes.CDLL 1bc

72 driver_lib = loader_cls(loaded_cuda.abs_path) 1bcd

73 cu_driver_get_version = driver_lib.cuDriverGetVersion 1bcd

74 cu_driver_get_version.argtypes = [ctypes.POINTER(ctypes.c_int)] 1bcd

75 cu_driver_get_version.restype = ctypes.c_int 1bcd

76 version = ctypes.c_int() 1bcd

77 status = cu_driver_get_version(ctypes.byref(version)) 1bcd

78 if status != 0: 1bcd

79 raise RuntimeError(f"Failed to query CUDA driver version via cuDriverGetVersion() (status={status}).") 1c

80 return version.value 1bd