From fe983b137a098ba559550100fa7bc4365287a928 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 20 Mar 2026 18:24:32 +0800 Subject: [PATCH] deps(nvidia-ml-py): add `nvidia-ml-py` 13.595.45 to support list --- .pre-commit-config.yaml | 4 +- CHANGELOG.md | 2 +- nvitop/api/device.py | 1 + nvitop/api/libnvml.py | 97 +++++++++++++++++++++++++++++++++++++++++ nvitop/version.py | 1 + pyproject.toml | 2 +- requirements.txt | 2 +- 7 files changed, 104 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ca1f57a..ad38e0c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,14 +29,14 @@ repos: args: [--ignore-case] files: ^docs/source/spelling_wordlist\.txt$ - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.1 + rev: v0.15.7 hooks: - id: ruff-check args: [--fix, --exit-non-zero-on-fix] - id: ruff-format args: [--exit-non-zero-on-format] - repo: https://github.com/codespell-project/codespell - rev: v2.4.1 + rev: v2.4.2 hooks: - id: codespell additional_dependencies: [".[toml]"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b35393..c7f20c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- +- Add `nvidia-ml-py` 13.595.45 to support list. ### Changed diff --git a/nvitop/api/device.py b/nvitop/api/device.py index f34338a..af52be7 100644 --- a/nvitop/api/device.py +++ b/nvitop/api/device.py @@ -2107,6 +2107,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me return { libnvml.NVML_DRIVER_WDDM: 'WDDM', libnvml.NVML_DRIVER_WDM: 'WDM', + libnvml.NVML_DRIVER_MCDM: 'MCDM', }.get(libnvml.nvmlQuery('nvmlDeviceGetCurrentDriverModel', self._handle), NA) return NA diff --git a/nvitop/api/libnvml.py b/nvitop/api/libnvml.py index 6391f97..7153b09 100644 --- a/nvitop/api/libnvml.py +++ b/nvitop/api/libnvml.py @@ -200,6 +200,7 @@ NVML_CLOCK_VIDEO: int = _pynvml.NVML_CLOCK_VIDEO NVML_TEMPERATURE_GPU: int = _pynvml.NVML_TEMPERATURE_GPU NVML_DRIVER_WDDM: int = _pynvml.NVML_DRIVER_WDDM NVML_DRIVER_WDM: int = _pynvml.NVML_DRIVER_WDM +NVML_DRIVER_MCDM: int = getattr(_pynvml, 'NVML_DRIVER_MCDM', 2) NVML_MEMORY_ERROR_TYPE_UNCORRECTED: int = _pynvml.NVML_MEMORY_ERROR_TYPE_UNCORRECTED NVML_VOLATILE_ECC: int = _pynvml.NVML_VOLATILE_ECC NVML_COMPUTEMODE_DEFAULT: int = _pynvml.NVML_COMPUTEMODE_DEFAULT @@ -978,6 +979,102 @@ else: '`nvidia-ml-py` via `pip3 install --force-reinstall nvidia-ml-py nvitop`.', ) +# Patch function `nvmlDeviceGetDriverModel` +# Since `nvidia-ml-py` 13.595.45, `nvmlDeviceGetDriverModel` dispatches to `_v2` which calls the +# C function `nvmlDeviceGetDriverModel_v2`. Older drivers may not have this symbol. +if not _pynvml_installation_corrupted: + __get_driver_model_version_suffix: str | None = None + + def __determine_get_driver_model_version_suffix() -> str: + global __get_driver_model_version_suffix # pylint: disable=global-statement + + if __get_driver_model_version_suffix is None: + __get_driver_model_version_suffix = '_v2' + if _nvmlLookupFunctionPointer('nvmlDeviceGetDriverModel_v2') is not None: + LOGGER.debug('NVML get driver model version 2 API is available.') + else: + __get_driver_model_version_suffix = '' + LOGGER.debug( + 'NVML get driver model version 2 API is not available due to incompatible ' + 'NVIDIA driver. Fallback to use NVML get driver model version 1 API.', + ) + + return __get_driver_model_version_suffix + + def nvmlDeviceGetDriverModel( # pylint: disable=function-redefined + handle: c_nvmlDevice_t, + ) -> list[int]: + """Retrieve the driver model (WDDM or WDM/TCC) for the device. + + Returns a list of two values: [current driver model, pending driver model]. + + Raises: + NVMLError_Uninitialized: + If NVML was not first initialized with :func:`nvmlInit`. + NVMLError_InvalidArgument: + If device is invalid. + NVMLError_GpuIsLost: + If the target GPU has fallen off the bus or is otherwise inaccessible. + NVMLError_NotSupported: + If the device does not support this feature (e.g. on Linux). + NVMLError_Unknown: + On any unexpected error. + """ + version_suffix = __determine_get_driver_model_version_suffix() + c_curr_model = _ctypes.c_uint() + c_pending_model = _ctypes.c_uint() + fn = _nvmlGetFunctionPointer(f'nvmlDeviceGetDriverModel{version_suffix}') + ret = fn(handle, _ctypes.byref(c_curr_model), _ctypes.byref(c_pending_model)) + if ret != NVML_SUCCESS: + raise NVMLError(ret) + return [c_curr_model.value, c_pending_model.value] + + def nvmlDeviceGetCurrentDriverModel( # pylint: disable=function-redefined + handle: c_nvmlDevice_t, + ) -> int: + """Retrieve the current driver model (WDDM or WDM/TCC) for the device. + + Raises: + NVMLError_Uninitialized: + If NVML was not first initialized with :func:`nvmlInit`. + NVMLError_InvalidArgument: + If device is invalid. + NVMLError_GpuIsLost: + If the target GPU has fallen off the bus or is otherwise inaccessible. + NVMLError_NotSupported: + If the device does not support this feature (e.g. on Linux). + NVMLError_Unknown: + On any unexpected error. + """ + return nvmlDeviceGetDriverModel(handle)[0] + + def nvmlDeviceGetPendingDriverModel( # pylint: disable=function-redefined + handle: c_nvmlDevice_t, + ) -> int: + """Retrieve the pending driver model (WDDM or WDM/TCC) for the device. + + Raises: + NVMLError_Uninitialized: + If NVML was not first initialized with :func:`nvmlInit`. + NVMLError_InvalidArgument: + If device is invalid. + NVMLError_GpuIsLost: + If the target GPU has fallen off the bus or is otherwise inaccessible. + NVMLError_NotSupported: + If the device does not support this feature (e.g. on Linux). + NVMLError_Unknown: + On any unexpected error. + """ + return nvmlDeviceGetDriverModel(handle)[1] + +else: + LOGGER.warning( + 'Your installed package `nvidia-ml-py` is corrupted. ' + 'Skip patch functions `nvmlDeviceGetDriverModel`. ' + 'You may get incorrect or incomplete results. Please consider reinstall package ' + '`nvidia-ml-py` via `pip3 install --force-reinstall nvidia-ml-py nvitop`.', + ) + # Add support for lookup fallback and context manager ############################################## class _CustomModule(_ModuleType): diff --git a/nvitop/version.py b/nvitop/version.py index 812e0df..e9941e2 100644 --- a/nvitop/version.py +++ b/nvitop/version.py @@ -97,6 +97,7 @@ PYNVML_VERSION_CANDIDATES = ( '13.580.126', '13.590.44', '13.590.48', + '13.595.45', ) """The list of supported ``nvidia-ml-py`` versions. See also: `nvidia-ml-py's Release History `_. diff --git a/pyproject.toml b/pyproject.toml index 82c90f4..3b3b544 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ classifiers = [ ] dependencies = [ # Sync with nvitop/version.py and requirements.txt - "nvidia-ml-py >= 11.450.51, < 13.591.0a0", + "nvidia-ml-py >= 11.450.51, < 13.596.0a0", "psutil >= 5.6.6", "colorama >= 0.4.0; platform_system == 'Windows'", "windows-curses >= 2.2.0; platform_system == 'Windows'", diff --git a/requirements.txt b/requirements.txt index 5d3f191..1ed5280 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Sync with pyproject.toml and nvitop/version.py -nvidia-ml-py >= 11.450.51, < 13.591.0a0 +nvidia-ml-py >= 11.450.51, < 13.596.0a0 psutil >= 5.6.6 colorama >= 0.4.0; platform_system == 'Windows' windows-curses >= 2.2.0; platform_system == 'Windows'