commit 4712ff518f4e5bfc80ac508768784d8169fb66b5 Author: clore Date: Tue Apr 30 13:33:13 2024 +0000 pure pynvml-11.5.0 diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..cd2e942 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2011-2021, NVIDIA Corporation. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of staged-recipes nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..cba4aa1 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,2 @@ +include versioneer.py +include pynvml/_version.py diff --git a/PKG-INFO b/PKG-INFO new file mode 100644 index 0000000..c767bf8 --- /dev/null +++ b/PKG-INFO @@ -0,0 +1,233 @@ +Metadata-Version: 2.1 +Name: pynvml +Version: 11.5.0 +Summary: Python Bindings for the NVIDIA Management Library +Home-page: http://www.nvidia.com/ +Author: NVIDIA Corporation +Author-email: rzamora@nvidia.com +License: BSD +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX :: Linux +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: System :: Hardware +Classifier: Topic :: System :: Systems Administration +Requires-Python: >=3.6 +Description-Content-Type: text/markdown +License-File: LICENSE.txt + +Python bindings to the NVIDIA Management Library +================================================ + +Provides a Python interface to GPU management and monitoring functions. + +This is a wrapper around the NVML library. +For information about the NVML library, see the NVML developer page +http://developer.nvidia.com/nvidia-management-library-nvml + +As of version 11.0.0, the NVML-wrappers used in pynvml are identical +to those published through [nvidia-ml-py](https://pypi.org/project/nvidia-ml-py/). + +Note that this file can be run with 'python -m doctest -v README.txt' +although the results are system dependent + +Requires +-------- +Python 3, or an earlier version with the ctypes module. + +Installation +------------ + + pip install . + +Usage +----- + +You can use the lower level nvml bindings + +```python +>>> from pynvml import * +>>> nvmlInit() +>>> print("Driver Version:", nvmlSystemGetDriverVersion()) +Driver Version: 410.00 +>>> deviceCount = nvmlDeviceGetCount() +>>> for i in range(deviceCount): +... handle = nvmlDeviceGetHandleByIndex(i) +... print("Device", i, ":", nvmlDeviceGetName(handle)) +... +Device 0 : Tesla V100 + +>>> nvmlShutdown() +``` + +Or the higher level nvidia_smi API + +```python +from pynvml.smi import nvidia_smi +nvsmi = nvidia_smi.getInstance() +nvsmi.DeviceQuery('memory.free, memory.total') +``` + +```python +from pynvml.smi import nvidia_smi +nvsmi = nvidia_smi.getInstance() +print(nvsmi.DeviceQuery('--help-query-gpu'), end='\n') +``` + +Functions +--------- +Python methods wrap NVML functions, implemented in a C shared library. +Each function's use is the same with the following exceptions: + +- Instead of returning error codes, failing error codes are raised as + Python exceptions. + + ```python + >>> try: + ... nvmlDeviceGetCount() + ... except NVMLError as error: + ... print(error) + ... + Uninitialized + ``` + +- C function output parameters are returned from the corresponding + Python function left to right. + + ```c + nvmlReturn_t nvmlDeviceGetEccMode(nvmlDevice_t device, + nvmlEnableState_t *current, + nvmlEnableState_t *pending); + ``` + + ```python + >>> nvmlInit() + >>> handle = nvmlDeviceGetHandleByIndex(0) + >>> (current, pending) = nvmlDeviceGetEccMode(handle) + ``` + +- C structs are converted into Python classes. + + ```c + nvmlReturn_t DECLDIR nvmlDeviceGetMemoryInfo(nvmlDevice_t device, + nvmlMemory_t *memory); + typedef struct nvmlMemory_st { + unsigned long long total; + unsigned long long free; + unsigned long long used; + } nvmlMemory_t; + ``` + + ```python + >>> info = nvmlDeviceGetMemoryInfo(handle) + >>> print "Total memory:", info.total + Total memory: 5636292608 + >>> print "Free memory:", info.free + Free memory: 5578420224 + >>> print "Used memory:", info.used + Used memory: 57872384 + ``` + +- Python handles string buffer creation. + + ```c + nvmlReturn_t nvmlSystemGetDriverVersion(char* version, + unsigned int length); + ``` + + ```python + >>> version = nvmlSystemGetDriverVersion(); + >>> nvmlShutdown() + ``` + +For usage information see the NVML documentation. + +Variables +--------- + +All meaningful NVML constants and enums are exposed in Python. + +The NVML_VALUE_NOT_AVAILABLE constant is not used. Instead None is mapped to the field. + +NVML Permissions +---------------- + +Many of the `pynvml` wrappers assume that the underlying NVIDIA Management Library (NVML) API can be used without admin/root privileges. However, it is certainly possible for the system permissions to prevent pynvml from querying GPU performance counters. For example: + +``` +$ nvidia-smi nvlink -g 0 +GPU 0: Tesla V100-SXM2-32GB (UUID: GPU-96ab329d-7a1f-73a8-a9b7-18b4b2855f92) +NVML: Unable to get the NvLink link utilization counter control for link 0: Insufficient Permissions +``` + +A simple way to check the permissions status is to look for `RmProfilingAdminOnly` in the driver `params` file (Note that `RmProfilingAdminOnly == 1` means that admin/sudo access is required): + +``` +$ cat /proc/driver/nvidia/params | grep RmProfilingAdminOnly +RmProfilingAdminOnly: 1 +``` + +For more information on setting/unsetting the relevant admin privileges, see [these notes](https://developer.nvidia.com/nvidia-development-tools-solutions-ERR_NVGPUCTRPERM-permission-issue-performance-counters) on resolving `ERR_NVGPUCTRPERM` errors. + + +Release Notes +------------- + +- Version 2.285.0 + - Added new functions for NVML 2.285. See NVML documentation for more information. + - Ported to support Python 3.0 and Python 2.0 syntax. + - Added nvidia_smi.py tool as a sample app. +- Version 3.295.0 + - Added new functions for NVML 3.295. See NVML documentation for more information. + - Updated nvidia_smi.py tool + - Includes additional error handling +- Version 4.304.0 + - Added new functions for NVML 4.304. See NVML documentation for more information. + - Updated nvidia_smi.py tool +- Version 4.304.3 + - Fixing nvmlUnitGetDeviceCount bug +- Version 5.319.0 + - Added new functions for NVML 5.319. See NVML documentation for more information. +- Version 6.340.0 + - Added new functions for NVML 6.340. See NVML documentation for more information. +- Version 7.346.0 + - Added new functions for NVML 7.346. See NVML documentation for more information. +- Version 7.352.0 + - Added new functions for NVML 7.352. See NVML documentation for more information. +- Version 8.0.0 + - Refactor code to a nvidia_smi singleton class + - Added DeviceQuery that returns a dictionary of (name, value). + - Added filter parameters on DeviceQuery to match query api in nvidia-smi + - Added filter parameters on XmlDeviceQuery to match query api in nvidia-smi + - Added integer enumeration for filter strings to reduce overhead for performance monitoring. + - Added loop(filter) method with async and callback support +- Version 8.0.1 + - Restructuring directories into two packages (pynvml and nvidia_smi) + - Adding initial tests for both packages + - Some name-convention cleanup in pynvml +- Version 8.0.2 + - Added NVLink function wrappers for pynvml module +- Version 8.0.3 + - Added versioneer + - Fixed nvmlDeviceGetNvLinkUtilizationCounter bug +- Version 8.0.4 + - Added nvmlDeviceGetTotalEnergyConsumption + - Added notes about NVML permissions + - Fixed version-check testing +- Version 11.0.0 + - Updated nvml.py to CUDA 11 + - Updated smi.py DeviceQuery to R460 + - Aligned nvml.py with latest nvidia-ml-py deployment +- Version 11.4.0 + - Updated nvml.py to CUDA 11.4 + - Updated smi.py NVML_BRAND_NAMES + - Aligned nvml.py with latest nvidia-ml-py deployment (11.495.46) +- Version 11.4.1 + - Fix comma bugs in nvml.py +- Version 11.5.0 + - Updated nvml.py to support CUDA 11.5 and CUDA 12 + - Aligned with latest nvidia-ml-py deployment (11.525.84) diff --git a/README.md b/README.md new file mode 100755 index 0000000..d9381cf --- /dev/null +++ b/README.md @@ -0,0 +1,211 @@ +Python bindings to the NVIDIA Management Library +================================================ + +Provides a Python interface to GPU management and monitoring functions. + +This is a wrapper around the NVML library. +For information about the NVML library, see the NVML developer page +http://developer.nvidia.com/nvidia-management-library-nvml + +As of version 11.0.0, the NVML-wrappers used in pynvml are identical +to those published through [nvidia-ml-py](https://pypi.org/project/nvidia-ml-py/). + +Note that this file can be run with 'python -m doctest -v README.txt' +although the results are system dependent + +Requires +-------- +Python 3, or an earlier version with the ctypes module. + +Installation +------------ + + pip install . + +Usage +----- + +You can use the lower level nvml bindings + +```python +>>> from pynvml import * +>>> nvmlInit() +>>> print("Driver Version:", nvmlSystemGetDriverVersion()) +Driver Version: 410.00 +>>> deviceCount = nvmlDeviceGetCount() +>>> for i in range(deviceCount): +... handle = nvmlDeviceGetHandleByIndex(i) +... print("Device", i, ":", nvmlDeviceGetName(handle)) +... +Device 0 : Tesla V100 + +>>> nvmlShutdown() +``` + +Or the higher level nvidia_smi API + +```python +from pynvml.smi import nvidia_smi +nvsmi = nvidia_smi.getInstance() +nvsmi.DeviceQuery('memory.free, memory.total') +``` + +```python +from pynvml.smi import nvidia_smi +nvsmi = nvidia_smi.getInstance() +print(nvsmi.DeviceQuery('--help-query-gpu'), end='\n') +``` + +Functions +--------- +Python methods wrap NVML functions, implemented in a C shared library. +Each function's use is the same with the following exceptions: + +- Instead of returning error codes, failing error codes are raised as + Python exceptions. + + ```python + >>> try: + ... nvmlDeviceGetCount() + ... except NVMLError as error: + ... print(error) + ... + Uninitialized + ``` + +- C function output parameters are returned from the corresponding + Python function left to right. + + ```c + nvmlReturn_t nvmlDeviceGetEccMode(nvmlDevice_t device, + nvmlEnableState_t *current, + nvmlEnableState_t *pending); + ``` + + ```python + >>> nvmlInit() + >>> handle = nvmlDeviceGetHandleByIndex(0) + >>> (current, pending) = nvmlDeviceGetEccMode(handle) + ``` + +- C structs are converted into Python classes. + + ```c + nvmlReturn_t DECLDIR nvmlDeviceGetMemoryInfo(nvmlDevice_t device, + nvmlMemory_t *memory); + typedef struct nvmlMemory_st { + unsigned long long total; + unsigned long long free; + unsigned long long used; + } nvmlMemory_t; + ``` + + ```python + >>> info = nvmlDeviceGetMemoryInfo(handle) + >>> print "Total memory:", info.total + Total memory: 5636292608 + >>> print "Free memory:", info.free + Free memory: 5578420224 + >>> print "Used memory:", info.used + Used memory: 57872384 + ``` + +- Python handles string buffer creation. + + ```c + nvmlReturn_t nvmlSystemGetDriverVersion(char* version, + unsigned int length); + ``` + + ```python + >>> version = nvmlSystemGetDriverVersion(); + >>> nvmlShutdown() + ``` + +For usage information see the NVML documentation. + +Variables +--------- + +All meaningful NVML constants and enums are exposed in Python. + +The NVML_VALUE_NOT_AVAILABLE constant is not used. Instead None is mapped to the field. + +NVML Permissions +---------------- + +Many of the `pynvml` wrappers assume that the underlying NVIDIA Management Library (NVML) API can be used without admin/root privileges. However, it is certainly possible for the system permissions to prevent pynvml from querying GPU performance counters. For example: + +``` +$ nvidia-smi nvlink -g 0 +GPU 0: Tesla V100-SXM2-32GB (UUID: GPU-96ab329d-7a1f-73a8-a9b7-18b4b2855f92) +NVML: Unable to get the NvLink link utilization counter control for link 0: Insufficient Permissions +``` + +A simple way to check the permissions status is to look for `RmProfilingAdminOnly` in the driver `params` file (Note that `RmProfilingAdminOnly == 1` means that admin/sudo access is required): + +``` +$ cat /proc/driver/nvidia/params | grep RmProfilingAdminOnly +RmProfilingAdminOnly: 1 +``` + +For more information on setting/unsetting the relevant admin privileges, see [these notes](https://developer.nvidia.com/nvidia-development-tools-solutions-ERR_NVGPUCTRPERM-permission-issue-performance-counters) on resolving `ERR_NVGPUCTRPERM` errors. + + +Release Notes +------------- + +- Version 2.285.0 + - Added new functions for NVML 2.285. See NVML documentation for more information. + - Ported to support Python 3.0 and Python 2.0 syntax. + - Added nvidia_smi.py tool as a sample app. +- Version 3.295.0 + - Added new functions for NVML 3.295. See NVML documentation for more information. + - Updated nvidia_smi.py tool + - Includes additional error handling +- Version 4.304.0 + - Added new functions for NVML 4.304. See NVML documentation for more information. + - Updated nvidia_smi.py tool +- Version 4.304.3 + - Fixing nvmlUnitGetDeviceCount bug +- Version 5.319.0 + - Added new functions for NVML 5.319. See NVML documentation for more information. +- Version 6.340.0 + - Added new functions for NVML 6.340. See NVML documentation for more information. +- Version 7.346.0 + - Added new functions for NVML 7.346. See NVML documentation for more information. +- Version 7.352.0 + - Added new functions for NVML 7.352. See NVML documentation for more information. +- Version 8.0.0 + - Refactor code to a nvidia_smi singleton class + - Added DeviceQuery that returns a dictionary of (name, value). + - Added filter parameters on DeviceQuery to match query api in nvidia-smi + - Added filter parameters on XmlDeviceQuery to match query api in nvidia-smi + - Added integer enumeration for filter strings to reduce overhead for performance monitoring. + - Added loop(filter) method with async and callback support +- Version 8.0.1 + - Restructuring directories into two packages (pynvml and nvidia_smi) + - Adding initial tests for both packages + - Some name-convention cleanup in pynvml +- Version 8.0.2 + - Added NVLink function wrappers for pynvml module +- Version 8.0.3 + - Added versioneer + - Fixed nvmlDeviceGetNvLinkUtilizationCounter bug +- Version 8.0.4 + - Added nvmlDeviceGetTotalEnergyConsumption + - Added notes about NVML permissions + - Fixed version-check testing +- Version 11.0.0 + - Updated nvml.py to CUDA 11 + - Updated smi.py DeviceQuery to R460 + - Aligned nvml.py with latest nvidia-ml-py deployment +- Version 11.4.0 + - Updated nvml.py to CUDA 11.4 + - Updated smi.py NVML_BRAND_NAMES + - Aligned nvml.py with latest nvidia-ml-py deployment (11.495.46) +- Version 11.4.1 + - Fix comma bugs in nvml.py +- Version 11.5.0 + - Updated nvml.py to support CUDA 11.5 and CUDA 12 + - Aligned with latest nvidia-ml-py deployment (11.525.84) diff --git a/pynvml.egg-info/PKG-INFO b/pynvml.egg-info/PKG-INFO new file mode 100644 index 0000000..c767bf8 --- /dev/null +++ b/pynvml.egg-info/PKG-INFO @@ -0,0 +1,233 @@ +Metadata-Version: 2.1 +Name: pynvml +Version: 11.5.0 +Summary: Python Bindings for the NVIDIA Management Library +Home-page: http://www.nvidia.com/ +Author: NVIDIA Corporation +Author-email: rzamora@nvidia.com +License: BSD +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX :: Linux +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: System :: Hardware +Classifier: Topic :: System :: Systems Administration +Requires-Python: >=3.6 +Description-Content-Type: text/markdown +License-File: LICENSE.txt + +Python bindings to the NVIDIA Management Library +================================================ + +Provides a Python interface to GPU management and monitoring functions. + +This is a wrapper around the NVML library. +For information about the NVML library, see the NVML developer page +http://developer.nvidia.com/nvidia-management-library-nvml + +As of version 11.0.0, the NVML-wrappers used in pynvml are identical +to those published through [nvidia-ml-py](https://pypi.org/project/nvidia-ml-py/). + +Note that this file can be run with 'python -m doctest -v README.txt' +although the results are system dependent + +Requires +-------- +Python 3, or an earlier version with the ctypes module. + +Installation +------------ + + pip install . + +Usage +----- + +You can use the lower level nvml bindings + +```python +>>> from pynvml import * +>>> nvmlInit() +>>> print("Driver Version:", nvmlSystemGetDriverVersion()) +Driver Version: 410.00 +>>> deviceCount = nvmlDeviceGetCount() +>>> for i in range(deviceCount): +... handle = nvmlDeviceGetHandleByIndex(i) +... print("Device", i, ":", nvmlDeviceGetName(handle)) +... +Device 0 : Tesla V100 + +>>> nvmlShutdown() +``` + +Or the higher level nvidia_smi API + +```python +from pynvml.smi import nvidia_smi +nvsmi = nvidia_smi.getInstance() +nvsmi.DeviceQuery('memory.free, memory.total') +``` + +```python +from pynvml.smi import nvidia_smi +nvsmi = nvidia_smi.getInstance() +print(nvsmi.DeviceQuery('--help-query-gpu'), end='\n') +``` + +Functions +--------- +Python methods wrap NVML functions, implemented in a C shared library. +Each function's use is the same with the following exceptions: + +- Instead of returning error codes, failing error codes are raised as + Python exceptions. + + ```python + >>> try: + ... nvmlDeviceGetCount() + ... except NVMLError as error: + ... print(error) + ... + Uninitialized + ``` + +- C function output parameters are returned from the corresponding + Python function left to right. + + ```c + nvmlReturn_t nvmlDeviceGetEccMode(nvmlDevice_t device, + nvmlEnableState_t *current, + nvmlEnableState_t *pending); + ``` + + ```python + >>> nvmlInit() + >>> handle = nvmlDeviceGetHandleByIndex(0) + >>> (current, pending) = nvmlDeviceGetEccMode(handle) + ``` + +- C structs are converted into Python classes. + + ```c + nvmlReturn_t DECLDIR nvmlDeviceGetMemoryInfo(nvmlDevice_t device, + nvmlMemory_t *memory); + typedef struct nvmlMemory_st { + unsigned long long total; + unsigned long long free; + unsigned long long used; + } nvmlMemory_t; + ``` + + ```python + >>> info = nvmlDeviceGetMemoryInfo(handle) + >>> print "Total memory:", info.total + Total memory: 5636292608 + >>> print "Free memory:", info.free + Free memory: 5578420224 + >>> print "Used memory:", info.used + Used memory: 57872384 + ``` + +- Python handles string buffer creation. + + ```c + nvmlReturn_t nvmlSystemGetDriverVersion(char* version, + unsigned int length); + ``` + + ```python + >>> version = nvmlSystemGetDriverVersion(); + >>> nvmlShutdown() + ``` + +For usage information see the NVML documentation. + +Variables +--------- + +All meaningful NVML constants and enums are exposed in Python. + +The NVML_VALUE_NOT_AVAILABLE constant is not used. Instead None is mapped to the field. + +NVML Permissions +---------------- + +Many of the `pynvml` wrappers assume that the underlying NVIDIA Management Library (NVML) API can be used without admin/root privileges. However, it is certainly possible for the system permissions to prevent pynvml from querying GPU performance counters. For example: + +``` +$ nvidia-smi nvlink -g 0 +GPU 0: Tesla V100-SXM2-32GB (UUID: GPU-96ab329d-7a1f-73a8-a9b7-18b4b2855f92) +NVML: Unable to get the NvLink link utilization counter control for link 0: Insufficient Permissions +``` + +A simple way to check the permissions status is to look for `RmProfilingAdminOnly` in the driver `params` file (Note that `RmProfilingAdminOnly == 1` means that admin/sudo access is required): + +``` +$ cat /proc/driver/nvidia/params | grep RmProfilingAdminOnly +RmProfilingAdminOnly: 1 +``` + +For more information on setting/unsetting the relevant admin privileges, see [these notes](https://developer.nvidia.com/nvidia-development-tools-solutions-ERR_NVGPUCTRPERM-permission-issue-performance-counters) on resolving `ERR_NVGPUCTRPERM` errors. + + +Release Notes +------------- + +- Version 2.285.0 + - Added new functions for NVML 2.285. See NVML documentation for more information. + - Ported to support Python 3.0 and Python 2.0 syntax. + - Added nvidia_smi.py tool as a sample app. +- Version 3.295.0 + - Added new functions for NVML 3.295. See NVML documentation for more information. + - Updated nvidia_smi.py tool + - Includes additional error handling +- Version 4.304.0 + - Added new functions for NVML 4.304. See NVML documentation for more information. + - Updated nvidia_smi.py tool +- Version 4.304.3 + - Fixing nvmlUnitGetDeviceCount bug +- Version 5.319.0 + - Added new functions for NVML 5.319. See NVML documentation for more information. +- Version 6.340.0 + - Added new functions for NVML 6.340. See NVML documentation for more information. +- Version 7.346.0 + - Added new functions for NVML 7.346. See NVML documentation for more information. +- Version 7.352.0 + - Added new functions for NVML 7.352. See NVML documentation for more information. +- Version 8.0.0 + - Refactor code to a nvidia_smi singleton class + - Added DeviceQuery that returns a dictionary of (name, value). + - Added filter parameters on DeviceQuery to match query api in nvidia-smi + - Added filter parameters on XmlDeviceQuery to match query api in nvidia-smi + - Added integer enumeration for filter strings to reduce overhead for performance monitoring. + - Added loop(filter) method with async and callback support +- Version 8.0.1 + - Restructuring directories into two packages (pynvml and nvidia_smi) + - Adding initial tests for both packages + - Some name-convention cleanup in pynvml +- Version 8.0.2 + - Added NVLink function wrappers for pynvml module +- Version 8.0.3 + - Added versioneer + - Fixed nvmlDeviceGetNvLinkUtilizationCounter bug +- Version 8.0.4 + - Added nvmlDeviceGetTotalEnergyConsumption + - Added notes about NVML permissions + - Fixed version-check testing +- Version 11.0.0 + - Updated nvml.py to CUDA 11 + - Updated smi.py DeviceQuery to R460 + - Aligned nvml.py with latest nvidia-ml-py deployment +- Version 11.4.0 + - Updated nvml.py to CUDA 11.4 + - Updated smi.py NVML_BRAND_NAMES + - Aligned nvml.py with latest nvidia-ml-py deployment (11.495.46) +- Version 11.4.1 + - Fix comma bugs in nvml.py +- Version 11.5.0 + - Updated nvml.py to support CUDA 11.5 and CUDA 12 + - Aligned with latest nvidia-ml-py deployment (11.525.84) diff --git a/pynvml.egg-info/SOURCES.txt b/pynvml.egg-info/SOURCES.txt new file mode 100644 index 0000000..87616b0 --- /dev/null +++ b/pynvml.egg-info/SOURCES.txt @@ -0,0 +1,14 @@ +LICENSE.txt +MANIFEST.in +README.md +setup.cfg +setup.py +versioneer.py +pynvml/__init__.py +pynvml/_version.py +pynvml/nvml.py +pynvml/smi.py +pynvml.egg-info/PKG-INFO +pynvml.egg-info/SOURCES.txt +pynvml.egg-info/dependency_links.txt +pynvml.egg-info/top_level.txt \ No newline at end of file diff --git a/pynvml.egg-info/dependency_links.txt b/pynvml.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/pynvml.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/pynvml.egg-info/top_level.txt b/pynvml.egg-info/top_level.txt new file mode 100644 index 0000000..4d8a7ef --- /dev/null +++ b/pynvml.egg-info/top_level.txt @@ -0,0 +1 @@ +pynvml diff --git a/pynvml/__init__.py b/pynvml/__init__.py new file mode 100644 index 0000000..3881d0d --- /dev/null +++ b/pynvml/__init__.py @@ -0,0 +1,5 @@ +from .nvml import * + +from ._version import get_versions +__version__ = get_versions()['version'] +del get_versions diff --git a/pynvml/_version.py b/pynvml/_version.py new file mode 100644 index 0000000..9c7b703 --- /dev/null +++ b/pynvml/_version.py @@ -0,0 +1,21 @@ + +# This file was generated by 'versioneer.py' (0.18) from +# revision-control system data, or from the parent directory name of an +# unpacked source archive. Distribution tarballs contain a pre-generated copy +# of this file. + +import json + +version_json = ''' +{ + "date": "2023-02-14T19:25:14-0800", + "dirty": false, + "error": null, + "full-revisionid": "43a7803c42358a87e765bb66373f3ae536d589a3", + "version": "11.5.0" +} +''' # END VERSION_JSON + + +def get_versions(): + return json.loads(version_json) diff --git a/pynvml/nvml.py b/pynvml/nvml.py new file mode 100644 index 0000000..d09894b --- /dev/null +++ b/pynvml/nvml.py @@ -0,0 +1,4532 @@ +##### +# Copyright (c) 2011-2023, NVIDIA Corporation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the NVIDIA Corporation nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +##### + +## +# Python bindings for the NVML library +## +from ctypes import * +from ctypes.util import find_library +from functools import wraps +import sys +import os +import threading +import string + +## C Type mappings ## +## Enums +_nvmlEnableState_t = c_uint +NVML_FEATURE_DISABLED = 0 +NVML_FEATURE_ENABLED = 1 + +_nvmlBrandType_t = c_uint +NVML_BRAND_UNKNOWN = 0 +NVML_BRAND_QUADRO = 1 +NVML_BRAND_TESLA = 2 +NVML_BRAND_NVS = 3 +NVML_BRAND_GRID = 4 # Deprecated from API reporting. Keeping definition for backward compatibility. +NVML_BRAND_GEFORCE = 5 +NVML_BRAND_TITAN = 6 +NVML_BRAND_NVIDIA_VAPPS = 7 # NVIDIA Virtual Applications +NVML_BRAND_NVIDIA_VPC = 8 # NVIDIA Virtual PC +NVML_BRAND_NVIDIA_VCS = 9 # NVIDIA Virtual Compute Server +NVML_BRAND_NVIDIA_VWS = 10 # NVIDIA RTX Virtual Workstation +NVML_BRAND_NVIDIA_CLOUD_GAMING = 11 # NVIDIA Cloud Gaming +NVML_BRAND_NVIDIA_VGAMING = NVML_BRAND_NVIDIA_CLOUD_GAMING # Deprecated from API reporting. Keeping definition for backward compatibility. +NVML_BRAND_QUADRO_RTX = 12 +NVML_BRAND_NVIDIA_RTX = 13 +NVML_BRAND_NVIDIA = 14 +NVML_BRAND_GEFORCE_RTX = 15 # Unused +NVML_BRAND_TITAN_RTX = 16 # Unused +NVML_BRAND_COUNT = 17 + +_nvmlTemperatureThresholds_t = c_uint +NVML_TEMPERATURE_THRESHOLD_SHUTDOWN = 0 +NVML_TEMPERATURE_THRESHOLD_SLOWDOWN = 1 +NVML_TEMPERATURE_THRESHOLD_MEM_MAX = 2 +NVML_TEMPERATURE_THRESHOLD_GPU_MAX = 3 +NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_MIN = 4 +NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_CURR = 5 +NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_MAX = 6 +NVML_TEMPERATURE_THRESHOLD_COUNT = 7 + +_nvmlTemperatureSensors_t = c_uint +NVML_TEMPERATURE_GPU = 0 +NVML_TEMPERATURE_COUNT = 1 + +_nvmlComputeMode_t = c_uint +NVML_COMPUTEMODE_DEFAULT = 0 +NVML_COMPUTEMODE_EXCLUSIVE_THREAD = 1 ## Support Removed +NVML_COMPUTEMODE_PROHIBITED = 2 +NVML_COMPUTEMODE_EXCLUSIVE_PROCESS = 3 +NVML_COMPUTEMODE_COUNT = 4 + +_nvmlMemoryLocation_t = c_uint +NVML_MEMORY_LOCATION_L1_CACHE = 0 +NVML_MEMORY_LOCATION_L2_CACHE = 1 +NVML_MEMORY_LOCATION_DEVICE_MEMORY = 2 +NVML_MEMORY_LOCATION_DRAM = 2 +NVML_MEMORY_LOCATION_REGISTER_FILE = 3 +NVML_MEMORY_LOCATION_TEXTURE_MEMORY = 4 +NVML_MEMORY_LOCATION_TEXTURE_SHM = 5 +NVML_MEMORY_LOCATION_CBU = 6 +NVML_MEMORY_LOCATION_SRAM = 7 +NVML_MEMORY_LOCATION_COUNT = 8 + +NVML_NVLINK_MAX_LINKS = 18 + +# For backwards compatibility, maintain the incorrectly-named "LANES" define +NVML_NVLINK_MAX_LANES = NVML_NVLINK_MAX_LINKS + +_nvmlNvLinkErrorCounter_t = c_uint +NVML_NVLINK_ERROR_DL_REPLAY = 0 +NVML_NVLINK_ERROR_DL_RECOVERY = 1 +NVML_NVLINK_ERROR_DL_CRC_FLIT = 2 +NVML_NVLINK_ERROR_DL_CRC_DATA = 3 +NVML_NVLINK_ERROR_DL_ECC_DATA = 4 +NVML_NVLINK_ERROR_COUNT = 5 + +_nvmlNvLinkEccLaneErrorCounter_t = c_uint +NVML_NVLINK_ERROR_DL_ECC_LANE0 = 0 +NVML_NVLINK_ERROR_DL_ECC_LANE1 = 1 +NVML_NVLINK_ERROR_DL_ECC_LANE2 = 2 +NVML_NVLINK_ERROR_DL_ECC_LANE3 = 3 +NVML_NVLINK_ERROR_DL_ECC_COUNT = 5 + +_nvmlNvLinkCapability_t = c_uint +NVML_NVLINK_CAP_P2P_SUPPORTED = 0 +NVML_NVLINK_CAP_SYSMEM_ACCESS = 1 +NVML_NVLINK_CAP_P2P_ATOMICS = 2 +NVML_NVLINK_CAP_SYSMEM_ATOMICS= 3 +NVML_NVLINK_CAP_SLI_BRIDGE = 4 +NVML_NVLINK_CAP_VALID = 5 +NVML_NVLINK_CAP_COUNT = 6 + +_nvmlNvLinkUtilizationCountPktTypes_t = c_uint +NVML_NVLINK_COUNTER_PKTFILTER_NOP = 0x1 +NVML_NVLINK_COUNTER_PKTFILTER_READ = 0x2 +NVML_NVLINK_COUNTER_PKTFILTER_WRITE = 0x4 +NVML_NVLINK_COUNTER_PKTFILTER_RATOM = 0x8 +NVML_NVLINK_COUNTER_PKTFILTER_NRATOM = 0x10 +NVML_NVLINK_COUNTER_PKTFILTER_FLUSH = 0x20 +NVML_NVLINK_COUNTER_PKTFILTER_RESPDATA = 0x40 +NVML_NVLINK_COUNTER_PKTFILTER_RESPNODATA = 0x80 +NVML_NVLINK_COUNTER_PKTFILTER_ALL = 0xFF + +_nvmlNvLinkUtilizationCountUnits_t = c_uint +NVML_NVLINK_COUNTER_UNIT_CYCLES = 0 +NVML_NVLINK_COUNTER_UNIT_PACKETS = 1 +NVML_NVLINK_COUNTER_UNIT_BYTES = 2 +NVML_NVLINK_COUNTER_UNIT_RESERVED = 3 +NVML_NVLINK_COUNTER_UNIT_COUNT = 4 + +_nvmlNvLinkDeviceType_t = c_uint +NVML_NVLINK_DEVICE_TYPE_GPU = 0x00 +NVML_NVLINK_DEVICE_TYPE_IBMNPU = 0x01 +NVML_NVLINK_DEVICE_TYPE_SWITCH = 0x02 +NVML_NVLINK_DEVICE_TYPE_UNKNOWN = 0xFF + +# These are deprecated, instead use _nvmlMemoryErrorType_t +_nvmlEccBitType_t = c_uint +NVML_SINGLE_BIT_ECC = 0 +NVML_DOUBLE_BIT_ECC = 1 +NVML_ECC_ERROR_TYPE_COUNT = 2 + +_nvmlEccCounterType_t = c_uint +NVML_VOLATILE_ECC = 0 +NVML_AGGREGATE_ECC = 1 +NVML_ECC_COUNTER_TYPE_COUNT = 2 + +_nvmlMemoryErrorType_t = c_uint +NVML_MEMORY_ERROR_TYPE_CORRECTED = 0 +NVML_MEMORY_ERROR_TYPE_UNCORRECTED = 1 +NVML_MEMORY_ERROR_TYPE_COUNT = 2 + +_nvmlClockType_t = c_uint +NVML_CLOCK_GRAPHICS = 0 +NVML_CLOCK_SM = 1 +NVML_CLOCK_MEM = 2 +NVML_CLOCK_VIDEO = 3 +NVML_CLOCK_COUNT = 4 + +_nvmlClockId_t = c_uint +NVML_CLOCK_ID_CURRENT = 0 +NVML_CLOCK_ID_APP_CLOCK_TARGET = 1 +NVML_CLOCK_ID_APP_CLOCK_DEFAULT = 2 +NVML_CLOCK_ID_CUSTOMER_BOOST_MAX = 3 +NVML_CLOCK_ID_COUNT = 4 + +_nvmlDriverModel_t = c_uint +NVML_DRIVER_WDDM = 0 +NVML_DRIVER_WDM = 1 +NVML_DRIVER_MCDM = 2 + +NVML_MAX_GPU_PERF_PSTATES = 16 + +_nvmlPstates_t = c_uint +NVML_PSTATE_0 = 0 +NVML_PSTATE_1 = 1 +NVML_PSTATE_2 = 2 +NVML_PSTATE_3 = 3 +NVML_PSTATE_4 = 4 +NVML_PSTATE_5 = 5 +NVML_PSTATE_6 = 6 +NVML_PSTATE_7 = 7 +NVML_PSTATE_8 = 8 +NVML_PSTATE_9 = 9 +NVML_PSTATE_10 = 10 +NVML_PSTATE_11 = 11 +NVML_PSTATE_12 = 12 +NVML_PSTATE_13 = 13 +NVML_PSTATE_14 = 14 +NVML_PSTATE_15 = 15 +NVML_PSTATE_UNKNOWN = 32 + +_nvmlInforomObject_t = c_uint +NVML_INFOROM_OEM = 0 +NVML_INFOROM_ECC = 1 +NVML_INFOROM_POWER = 2 +NVML_INFOROM_COUNT = 3 + +_nvmlReturn_t = c_uint +NVML_SUCCESS = 0 +NVML_ERROR_UNINITIALIZED = 1 +NVML_ERROR_INVALID_ARGUMENT = 2 +NVML_ERROR_NOT_SUPPORTED = 3 +NVML_ERROR_NO_PERMISSION = 4 +NVML_ERROR_ALREADY_INITIALIZED = 5 +NVML_ERROR_NOT_FOUND = 6 +NVML_ERROR_INSUFFICIENT_SIZE = 7 +NVML_ERROR_INSUFFICIENT_POWER = 8 +NVML_ERROR_DRIVER_NOT_LOADED = 9 +NVML_ERROR_TIMEOUT = 10 +NVML_ERROR_IRQ_ISSUE = 11 +NVML_ERROR_LIBRARY_NOT_FOUND = 12 +NVML_ERROR_FUNCTION_NOT_FOUND = 13 +NVML_ERROR_CORRUPTED_INFOROM = 14 +NVML_ERROR_GPU_IS_LOST = 15 +NVML_ERROR_RESET_REQUIRED = 16 +NVML_ERROR_OPERATING_SYSTEM = 17 +NVML_ERROR_LIB_RM_VERSION_MISMATCH = 18 +NVML_ERROR_IN_USE = 19 +NVML_ERROR_MEMORY = 20 +NVML_ERROR_NO_DATA = 21 +NVML_ERROR_VGPU_ECC_NOT_SUPPORTED = 22 +NVML_ERROR_INSUFFICIENT_RESOURCES = 23 +NVML_ERROR_FREQ_NOT_SUPPORTED = 24 +NVML_ERROR_ARGUMENT_VERSION_MISMATCH = 25 +NVML_ERROR_DEPRECATED = 26 +NVML_ERROR_UNKNOWN = 999 + +_nvmlFanState_t = c_uint +NVML_FAN_NORMAL = 0 +NVML_FAN_FAILED = 1 + +_nvmlFanControlPolicy_t = c_uint +NVML_FAN_POLICY_TEMPERATURE_CONTINOUS_SW = 0 +NVML_FAN_POLICY_MANUAL = 1 + +_nvmlLedColor_t = c_uint +NVML_LED_COLOR_GREEN = 0 +NVML_LED_COLOR_AMBER = 1 + +_nvmlGpuOperationMode_t = c_uint +NVML_GOM_ALL_ON = 0 +NVML_GOM_COMPUTE = 1 +NVML_GOM_LOW_DP = 2 + +_nvmlPageRetirementCause_t = c_uint +NVML_PAGE_RETIREMENT_CAUSE_MULTIPLE_SINGLE_BIT_ECC_ERRORS = 0 +NVML_PAGE_RETIREMENT_CAUSE_DOUBLE_BIT_ECC_ERROR = 1 +NVML_PAGE_RETIREMENT_CAUSE_COUNT = 2 + +_nvmlRestrictedAPI_t = c_uint +NVML_RESTRICTED_API_SET_APPLICATION_CLOCKS = 0 +NVML_RESTRICTED_API_SET_AUTO_BOOSTED_CLOCKS = 1 +NVML_RESTRICTED_API_COUNT = 2 + +_nvmlBridgeChipType_t = c_uint +NVML_BRIDGE_CHIP_PLX = 0 +NVML_BRIDGE_CHIP_BRO4 = 1 +NVML_MAX_PHYSICAL_BRIDGE = 128 + +_nvmlValueType_t = c_uint +NVML_VALUE_TYPE_DOUBLE = 0 +NVML_VALUE_TYPE_UNSIGNED_INT = 1 +NVML_VALUE_TYPE_UNSIGNED_LONG = 2 +NVML_VALUE_TYPE_UNSIGNED_LONG_LONG = 3 +NVML_VALUE_TYPE_SIGNED_LONG_LONG = 4 +NVML_VALUE_TYPE_COUNT = 5 + +_nvmlPerfPolicyType_t = c_uint +NVML_PERF_POLICY_POWER = 0 +NVML_PERF_POLICY_THERMAL = 1 +NVML_PERF_POLICY_SYNC_BOOST = 2 +NVML_PERF_POLICY_BOARD_LIMIT = 3 +NVML_PERF_POLICY_LOW_UTILIZATION = 4 +NVML_PERF_POLICY_RELIABILITY = 5 +NVML_PERF_POLICY_TOTAL_APP_CLOCKS = 10 +NVML_PERF_POLICY_TOTAL_BASE_CLOCKS = 11 +NVML_PERF_POLICY_COUNT = 12 + +_nvmlEncoderQueryType_t = c_uint +NVML_ENCODER_QUERY_H264 = 0 +NVML_ENCODER_QUERY_HEVC = 1 + +_nvmlFBCSessionType_t = c_uint +NVML_FBC_SESSION_TYPE_UNKNOWN = 0 +NVML_FBC_SESSION_TYPE_TOSYS = 1 +NVML_FBC_SESSION_TYPE_CUDA = 2 +NVML_FBC_SESSION_TYPE_VID = 3 +NVML_FBC_SESSION_TYPE_HWENC = 4 + +_nvmlDetachGpuState_t = c_uint +NVML_DETACH_GPU_KEEP = 0 +NVML_DETACH_GPU_REMOVE = 1 + +_nvmlPcieLinkState_t = c_uint +NVML_PCIE_LINK_KEEP = 0 +NVML_PCIE_LINK_SHUT_DOWN = 1 + +_nvmlSamplingType_t = c_uint +NVML_TOTAL_POWER_SAMPLES = 0 +NVML_GPU_UTILIZATION_SAMPLES = 1 +NVML_MEMORY_UTILIZATION_SAMPLES = 2 +NVML_ENC_UTILIZATION_SAMPLES = 3 +NVML_DEC_UTILIZATION_SAMPLES = 4 +NVML_PROCESSOR_CLK_SAMPLES = 5 +NVML_MEMORY_CLK_SAMPLES = 6 +NVML_SAMPLINGTYPE_COUNT = 7 + +_nvmlPcieUtilCounter_t = c_uint +NVML_PCIE_UTIL_TX_BYTES = 0 +NVML_PCIE_UTIL_RX_BYTES = 1 +NVML_PCIE_UTIL_COUNT = 2 + +_nvmlGpuTopologyLevel_t = c_uint +NVML_TOPOLOGY_INTERNAL = 0 +NVML_TOPOLOGY_SINGLE = 10 +NVML_TOPOLOGY_MULTIPLE = 20 +NVML_TOPOLOGY_HOSTBRIDGE = 30 +NVML_TOPOLOGY_NODE = 40 +NVML_TOPOLOGY_CPU = NVML_TOPOLOGY_NODE +NVML_TOPOLOGY_SYSTEM = 50 + +_nvmlGpuP2PCapsIndex_t = c_uint +NVML_P2P_CAPS_INDEX_READ = 0 +NVML_P2P_CAPS_INDEX_WRITE = 1 +NVML_P2P_CAPS_INDEX_NVLINK = 2 +NVML_P2P_CAPS_INDEX_ATOMICS = 3 +NVML_P2P_CAPS_INDEX_PROP = 4 +NVML_P2P_CAPS_INDEX_LOOPBACK = 5 +NVML_P2P_CAPS_INDEX_UNKNOWN = 6 + +_nvmlGpuP2PStatus_t = c_uint +NVML_P2P_STATUS_OK = 0 +NVML_P2P_STATUS_CHIPSET_NOT_SUPPORED = 1 +NVML_P2P_STATUS_GPU_NOT_SUPPORTED = 2 +NVML_P2P_STATUS_IOH_TOPOLOGY_NOT_SUPPORTED =3 +NVML_P2P_STATUS_DISABLED_BY_REGKEY =4 +NVML_P2P_STATUS_NOT_SUPPORTED =5 +NVML_P2P_STATUS_UNKNOWN =6 + +_nvmlDeviceArchitecture_t = c_uint +NVML_DEVICE_ARCH_KEPLER = 2 +NVML_DEVICE_ARCH_MAXWELL = 3 +NVML_DEVICE_ARCH_PASCAL = 4 +NVML_DEVICE_ARCH_VOLTA = 5 +NVML_DEVICE_ARCH_TURING = 6 +NVML_DEVICE_ARCH_AMPERE = 7 +NVML_DEVICE_ARCH_ADA = 8 +NVML_DEVICE_ARCH_HOPPER = 9 +NVML_DEVICE_ARCH_UNKNOWN = 0xffffffff + +# PCI bus Types +_nvmlBusType_t = c_uint +NVML_BUS_TYPE_UNKNOWN = 0 +NVML_BUS_TYPE_PCI = 1 +NVML_BUS_TYPE_PCIE = 2 +NVML_BUS_TYPE_FPCI = 3 +NVML_BUS_TYPE_AGP = 4 + +_nvmlPowerSource_t = c_uint +NVML_POWER_SOURCE_AC = 0x00000000 +NVML_POWER_SOURCE_BATTERY = 0x00000001 + +_nvmlAdaptiveClockInfoStatus_t = c_uint +NVML_ADAPTIVE_CLOCKING_INFO_STATUS_DISABLED = 0x00000000 +NVML_ADAPTIVE_CLOCKING_INFO_STATUS_ENABLED = 0x00000001 + +_nvmlClockLimitId_t = c_uint +NVML_CLOCK_LIMIT_ID_RANGE_START = 0xffffff00 +NVML_CLOCK_LIMIT_ID_TDP = 0xffffff01 +NVML_CLOCK_LIMIT_ID_UNLIMITED = 0xffffff02 + +_nvmlPcieLinkMaxSpeed_t = c_uint +NVML_PCIE_LINK_MAX_SPEED_INVALID = 0x00000000 +NVML_PCIE_LINK_MAX_SPEED_2500MBPS = 0x00000001 +NVML_PCIE_LINK_MAX_SPEED_5000MBPS = 0x00000002 +NVML_PCIE_LINK_MAX_SPEED_8000MBPS = 0x00000003 +NVML_PCIE_LINK_MAX_SPEED_16000MBPS = 0x00000004 +NVML_PCIE_LINK_MAX_SPEED_32000MBPS = 0x00000005 +NVML_PCIE_LINK_MAX_SPEED_64000MBPS = 0x00000006 + +_nvmlAffinityScope_t = c_uint +NVML_AFFINITY_SCOPE_NODE = 0 +NVML_AFFINITY_SCOPE_SOCKET = 1 + +# C preprocessor defined values +nvmlFlagDefault = 0 +nvmlFlagForce = 1 +NVML_INIT_FLAG_NO_GPUS = 1 +NVML_INIT_FLAG_NO_ATTACH = 2 + +NVML_MAX_GPC_COUNT = 32 + +# buffer size +NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE = 16 +NVML_DEVICE_UUID_BUFFER_SIZE = 80 +NVML_DEVICE_UUID_V2_BUFFER_SIZE = 96 +NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE = 80 +NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE = 80 +NVML_DEVICE_NAME_BUFFER_SIZE = 64 +NVML_DEVICE_NAME_V2_BUFFER_SIZE = 96 +NVML_DEVICE_SERIAL_BUFFER_SIZE = 30 +NVML_DEVICE_PART_NUMBER_BUFFER_SIZE = 80 +NVML_DEVICE_GPU_PART_NUMBER_BUFFER_SIZE = 80 +NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE = 32 +NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE = 32 +NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE = 16 +NVML_GRID_LICENSE_BUFFER_SIZE = 128 +NVML_VGPU_NAME_BUFFER_SIZE = 64 +NVML_GRID_LICENSE_FEATURE_MAX_COUNT = 3 +NVML_VGPU_METADATA_OPAQUE_DATA_SIZE = sizeof(c_uint) + 256 +NVML_VGPU_PGPU_METADATA_OPAQUE_DATA_SIZE = 256 + +# Format strings +NVML_DEVICE_PCI_BUS_ID_LEGACY_FMT = "%04X:%02X:%02X.0" +NVML_DEVICE_PCI_BUS_ID_FMT = "%08X:%02X:%02X.0" + +NVML_VALUE_NOT_AVAILABLE_ulonglong = c_ulonglong(-1) +NVML_VALUE_NOT_AVAILABLE_uint = c_uint(-1) + +''' + Field Identifiers. + + All Identifiers pertain to a device. Each ID is only used once and is guaranteed never to change. +''' +NVML_FI_DEV_ECC_CURRENT = 1 # Current ECC mode. 1=Active. 0=Inactive +NVML_FI_DEV_ECC_PENDING = 2 # Pending ECC mode. 1=Active. 0=Inactive + +#ECC Count Totals +NVML_FI_DEV_ECC_SBE_VOL_TOTAL = 3 # Total single bit volatile ECC errors +NVML_FI_DEV_ECC_DBE_VOL_TOTAL = 4 # Total double bit volatile ECC errors +NVML_FI_DEV_ECC_SBE_AGG_TOTAL = 5 # Total single bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_DBE_AGG_TOTAL = 6 # Total double bit aggregate (persistent) ECC errors +#Individual ECC locations +NVML_FI_DEV_ECC_SBE_VOL_L1 = 7 # L1 cache single bit volatile ECC errors +NVML_FI_DEV_ECC_DBE_VOL_L1 = 8 # L1 cache double bit volatile ECC errors +NVML_FI_DEV_ECC_SBE_VOL_L2 = 9 # L2 cache single bit volatile ECC errors +NVML_FI_DEV_ECC_DBE_VOL_L2 = 10 # L2 cache double bit volatile ECC errors +NVML_FI_DEV_ECC_SBE_VOL_DEV = 11 # Device memory single bit volatile ECC errors +NVML_FI_DEV_ECC_DBE_VOL_DEV = 12 # Device memory double bit volatile ECC errors +NVML_FI_DEV_ECC_SBE_VOL_REG = 13 # Register file single bit volatile ECC errors +NVML_FI_DEV_ECC_DBE_VOL_REG = 14 # Register file double bit volatile ECC errors +NVML_FI_DEV_ECC_SBE_VOL_TEX = 15 # Texture memory single bit volatile ECC errors +NVML_FI_DEV_ECC_DBE_VOL_TEX = 16 # Texture memory double bit volatile ECC errors +NVML_FI_DEV_ECC_DBE_VOL_CBU = 17 # CBU double bit volatile ECC errors +NVML_FI_DEV_ECC_SBE_AGG_L1 = 18 # L1 cache single bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_DBE_AGG_L1 = 19 # L1 cache double bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_SBE_AGG_L2 = 20 # L2 cache single bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_DBE_AGG_L2 = 21 # L2 cache double bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_SBE_AGG_DEV = 22 # Device memory single bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_DBE_AGG_DEV = 23 # Device memory double bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_SBE_AGG_REG = 24 # Register File single bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_DBE_AGG_REG = 25 # Register File double bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_SBE_AGG_TEX = 26 # Texture memory single bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_DBE_AGG_TEX = 27 # Texture memory double bit aggregate (persistent) ECC errors +NVML_FI_DEV_ECC_DBE_AGG_CBU = 28 # CBU double bit aggregate ECC errors + +# Page Retirement +NVML_FI_DEV_RETIRED_SBE = 29 # Number of retired pages because of single bit errors +NVML_FI_DEV_RETIRED_DBE = 30 # Number of retired pages because of double bit errors +NVML_FI_DEV_RETIRED_PENDING = 31 # If any pages are pending retirement. 1=yes. 0=no. + +# NvLink Flit Error Counters +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L0 = 32 # NVLink flow control CRC Error Counter for Lane 0 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L1 = 33 # NVLink flow control CRC Error Counter for Lane 1 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L2 = 34 # NVLink flow control CRC Error Counter for Lane 2 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L3 = 35 # NVLink flow control CRC Error Counter for Lane 3 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L4 = 36 # NVLink flow control CRC Error Counter for Lane 4 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L5 = 37 # NVLink flow control CRC Error Counter for Lane 5 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_TOTAL = 38 # NVLink flow control CRC Error Counter total for all Lanes + +# NvLink CRC Data Error Counters +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L0 = 39 # NVLink data CRC Error Counter for Lane 0 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L1 = 40 # NVLink data CRC Error Counter for Lane 1 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L2 = 41 # NVLink data CRC Error Counter for Lane 2 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L3 = 42 # NVLink data CRC Error Counter for Lane 3 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L4 = 43 # NVLink data CRC Error Counter for Lane 4 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L5 = 44 # NVLink data CRC Error Counter for Lane 5 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_TOTAL = 45 # NvLink data CRC Error Counter total for all Lanes + +# NvLink Replay Error Counters +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L0 = 46 # NVLink Replay Error Counter for Lane 0 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L1 = 47 # NVLink Replay Error Counter for Lane 1 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L2 = 48 # NVLink Replay Error Counter for Lane 2 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L3 = 49 # NVLink Replay Error Counter for Lane 3 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L4 = 50 # NVLink Replay Error Counter for Lane 4 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L5 = 51 # NVLink Replay Error Counter for Lane 5 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_TOTAL = 52 # NVLink Replay Error Counter total for all Lanes + +# NvLink Recovery Error Counters +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L0 = 53 # NVLink Recovery Error Counter for Lane 0 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L1 = 54 # NVLink Recovery Error Counter for Lane 1 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L2 = 55 # NVLink Recovery Error Counter for Lane 2 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L3 = 56 # NVLink Recovery Error Counter for Lane 3 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L4 = 57 # NVLink Recovery Error Counter for Lane 4 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L5 = 58 # NVLink Recovery Error Counter for Lane 5 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_TOTAL = 59 # NVLink Recovery Error Counter total for all Lanes + +# NvLink Bandwidth Counters +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L0 = 60 # NVLink Bandwidth Counter for Counter Set 0, Lane 0 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L1 = 61 # NVLink Bandwidth Counter for Counter Set 0, Lane 1 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L2 = 62 # NVLink Bandwidth Counter for Counter Set 0, Lane 2 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L3 = 63 # NVLink Bandwidth Counter for Counter Set 0, Lane 3 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L4 = 64 # NVLink Bandwidth Counter for Counter Set 0, Lane 4 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L5 = 65 # NVLink Bandwidth Counter for Counter Set 0, Lane 5 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_TOTAL = 66 # NVLink Bandwidth Counter Total for Counter Set 0, All Lanes + +# NvLink Bandwidth Counters +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L0 = 67 # NVLink Bandwidth Counter for Counter Set 1, Lane 0 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L1 = 68 # NVLink Bandwidth Counter for Counter Set 1, Lane 1 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L2 = 69 # NVLink Bandwidth Counter for Counter Set 1, Lane 2 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L3 = 70 # NVLink Bandwidth Counter for Counter Set 1, Lane 3 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L4 = 71 # NVLink Bandwidth Counter for Counter Set 1, Lane 4 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L5 = 72 # NVLink Bandwidth Counter for Counter Set 1, Lane 5 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_TOTAL = 73 # NVLink Bandwidth Counter Total for Counter Set 1, All Lanes + +# Perf Policy Counters +NVML_FI_DEV_PERF_POLICY_POWER = 74 # Perf Policy Counter for Power Policy +NVML_FI_DEV_PERF_POLICY_THERMAL = 75 # Perf Policy Counter for Thermal Policy +NVML_FI_DEV_PERF_POLICY_SYNC_BOOST = 76 # Perf Policy Counter for Sync boost Policy +NVML_FI_DEV_PERF_POLICY_BOARD_LIMIT = 77 # Perf Policy Counter for Board Limit +NVML_FI_DEV_PERF_POLICY_LOW_UTILIZATION = 78 # Perf Policy Counter for Low GPU Utilization Policy +NVML_FI_DEV_PERF_POLICY_RELIABILITY = 79 # Perf Policy Counter for Reliability Policy +NVML_FI_DEV_PERF_POLICY_TOTAL_APP_CLOCKS = 80 # Perf Policy Counter for Total App Clock Policy +NVML_FI_DEV_PERF_POLICY_TOTAL_BASE_CLOCKS = 81 # Perf Policy Counter for Total Base Clocks Policy + +# Memory temperatures +NVML_FI_DEV_MEMORY_TEMP = 82 # Memory temperature for the device + +# Energy Counter +NVML_FI_DEV_TOTAL_ENERGY_CONSUMPTION = 83 # Total energy consumption for the GPU in mJ since the driver was last reloaded + +# NVLink Speed +NVML_FI_DEV_NVLINK_SPEED_MBPS_L0 = 84 +NVML_FI_DEV_NVLINK_SPEED_MBPS_L1 = 85 +NVML_FI_DEV_NVLINK_SPEED_MBPS_L2 = 86 +NVML_FI_DEV_NVLINK_SPEED_MBPS_L3 = 87 +NVML_FI_DEV_NVLINK_SPEED_MBPS_L4 = 88 +NVML_FI_DEV_NVLINK_SPEED_MBPS_L5 = 89 +NVML_FI_DEV_NVLINK_SPEED_MBPS_COMMON = 90 + +# NVLink Link Count +NVML_FI_DEV_NVLINK_LINK_COUNT = 91 + +# Page Retirement pending fields +NVML_FI_DEV_RETIRED_PENDING_SBE = 92 +NVML_FI_DEV_RETIRED_PENDING_DBE = 93 + +# PCIe replay and replay rollover counters +NVML_FI_DEV_PCIE_REPLAY_COUNTER = 94 +NVML_FI_DEV_PCIE_REPLAY_ROLLOVER_COUNTER = 95 + +# NvLink Flit Error Counters +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L6 = 96 # NVLink flow control CRC Error Counter for Lane 6 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L7 = 97 # NVLink flow control CRC Error Counter for Lane 7 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L8 = 98 # NVLink flow control CRC Error Counter for Lane 8 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L9 = 99 # NVLink flow control CRC Error Counter for Lane 9 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L10 = 100 # NVLink flow control CRC Error Counter for Lane 10 +NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L11 = 101 # NVLink flow control CRC Error Counter for Lane 11 + +# NvLink CRC Data Error Counters +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L6 = 102 # NVLink data CRC Error Counter for Lane 6 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L7 = 103 # NVLink data CRC Error Counter for Lane 7 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L8 = 104 # NVLink data CRC Error Counter for Lane 8 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L9 = 105 # NVLink data CRC Error Counter for Lane 9 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L10 = 106 # NVLink data CRC Error Counter for Lane 10 +NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L11 = 107 # NVLink data CRC Error Counter for Lane 11 + +# NvLink Replay Error Counters +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L6 = 108 # NVLink Replay Error Counter for Lane 6 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L7 = 109 # NVLink Replay Error Counter for Lane 7 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L8 = 110 # NVLink Replay Error Counter for Lane 8 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L9 = 111 # NVLink Replay Error Counter for Lane 9 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L10 = 112 # NVLink Replay Error Counter for Lane 10 +NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L11 = 113 # NVLink Replay Error Counter for Lane 11 + +# NvLink Recovery Error Counters +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L6 = 114 # NVLink Recovery Error Counter for Lane 6 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L7 = 115 # NVLink Recovery Error Counter for Lane 7 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L8 = 116 # NVLink Recovery Error Counter for Lane 8 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L9 = 117 # NVLink Recovery Error Counter for Lane 9 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L10 = 118 # NVLink Recovery Error Counter for Lane 10 +NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L11 = 119 # NVLink Recovery Error Counter for Lane 11 + +# NvLink Bandwidth Counters +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L6 = 120 # NVLink Bandwidth Counter for Counter Set 0, Lane 6 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L7 = 121 # NVLink Bandwidth Counter for Counter Set 0, Lane 7 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L8 = 122 # NVLink Bandwidth Counter for Counter Set 0, Lane 8 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L9 = 123 # NVLink Bandwidth Counter for Counter Set 0, Lane 9 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L10 = 124 # NVLink Bandwidth Counter for Counter Set 0, Lane 10 +NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L11 = 125 # NVLink Bandwidth Counter for Counter Set 0, Lane 11 + +# NvLink Bandwidth Counters +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L6 = 126 # NVLink Bandwidth Counter for Counter Set 1, Lane 6 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L7 = 127 # NVLink Bandwidth Counter for Counter Set 1, Lane 7 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L8 = 128 # NVLink Bandwidth Counter for Counter Set 1, Lane 8 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L9 = 129 # NVLink Bandwidth Counter for Counter Set 1, Lane 9 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L10 = 130 # NVLink Bandwidth Counter for Counter Set 1, Lane 10 +NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L11 = 131 # NVLink Bandwidth Counter for Counter Set 1, Lane 11 + +# NVLink Speed +NVML_FI_DEV_NVLINK_SPEED_MBPS_L6 = 132 +NVML_FI_DEV_NVLINK_SPEED_MBPS_L7 = 133 +NVML_FI_DEV_NVLINK_SPEED_MBPS_L8 = 134 +NVML_FI_DEV_NVLINK_SPEED_MBPS_L9 = 135 +NVML_FI_DEV_NVLINK_SPEED_MBPS_L10 = 136 +NVML_FI_DEV_NVLINK_SPEED_MBPS_L11 = 137 + +# NVLink Throughput Counters +NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_TX = 138 # NVLink TX Data throughput in KiB +NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_RX = 139 # NVLink RX Data throughput in KiB +NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_TX = 140 # NVLink TX Data + protocol overhead in KiB +NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_RX = 141 # NVLink RX Data + protocol overhead in KiB + +# Row Remapper +NVML_FI_DEV_REMAPPED_COR = 142 +NVML_FI_DEV_REMAPPED_UNC = 143 +NVML_FI_DEV_REMAPPED_PENDING = 144 +NVML_FI_DEV_REMAPPED_FAILURE = 145 + +#Remote device NVLink ID +NVML_FI_DEV_NVLINK_REMOTE_NVLINK_ID = 146 + +# Number of NVLinks connected to NVSwitch +NVML_FI_DEV_NVSWITCH_CONNECTED_LINK_COUNT = 147 + +# NvLink ECC Data Error Counters +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L0 = 148 #< NVLink data ECC Error Counter for Link 0 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L1 = 149 #< NVLink data ECC Error Counter for Link 1 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L2 = 150 #< NVLink data ECC Error Counter for Link 2 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L3 = 151 #< NVLink data ECC Error Counter for Link 3 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L4 = 152 #< NVLink data ECC Error Counter for Link 4 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L5 = 153 #< NVLink data ECC Error Counter for Link 5 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L6 = 154 #< NVLink data ECC Error Counter for Link 6 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L7 = 155 #< NVLink data ECC Error Counter for Link 7 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L8 = 156 #< NVLink data ECC Error Counter for Link 8 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L9 = 157 #< NVLink data ECC Error Counter for Link 9 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L10 = 158 #< NVLink data ECC Error Counter for Link 10 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L11 = 159 #< NVLink data ECC Error Counter for Link 11 +NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_TOTAL = 160 #< NvLink data ECC Error Counter total for all Links + +NVML_FI_DEV_NVLINK_ERROR_DL_REPLAY = 161 +NVML_FI_DEV_NVLINK_ERROR_DL_RECOVERY = 162 +NVML_FI_DEV_NVLINK_ERROR_DL_CRC = 163 +NVML_FI_DEV_NVLINK_GET_SPEED = 164 +NVML_FI_DEV_NVLINK_GET_STATE = 165 +NVML_FI_DEV_NVLINK_GET_VERSION = 166 + +NVML_FI_DEV_NVLINK_GET_POWER_STATE = 167 +NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD = 168 + +NVML_FI_DEV_PCIE_L0_TO_RECOVERY_COUNTER = 169 + +NVML_FI_MAX = 170 # One greater than the largest field ID defined above + + +## Enums needed for the method nvmlDeviceGetVirtualizationMode and nvmlDeviceSetVirtualizationMode +NVML_GPU_VIRTUALIZATION_MODE_NONE = 0 # Represents Bare Metal GPU +NVML_GPU_VIRTUALIZATION_MODE_PASSTHROUGH = 1 # Device is associated with GPU-Passthorugh +NVML_GPU_VIRTUALIZATION_MODE_VGPU = 2 # Device is associated with vGPU inside virtual machine. +NVML_GPU_VIRTUALIZATION_MODE_HOST_VGPU = 3 # Device is associated with VGX hypervisor in vGPU mode +NVML_GPU_VIRTUALIZATION_MODE_HOST_VSGA = 4 # Device is associated with VGX hypervisor in vSGA mode + +## Lib loading ## +nvmlLib = None +libLoadLock = threading.Lock() +_nvmlLib_refcount = 0 # Incremented on each nvmlInit and decremented on nvmlShutdown + +## vGPU Management +_nvmlVgpuTypeId_t = c_uint +_nvmlVgpuInstance_t = c_uint + +_nvmlVgpuVmIdType_t = c_uint +NVML_VGPU_VM_ID_DOMAIN_ID = 0 +NVML_VGPU_VM_ID_UUID = 1 + +_nvmlGridLicenseFeatureCode_t = c_uint +NVML_GRID_LICENSE_FEATURE_CODE_UNKNOWN = 0 +NVML_GRID_LICENSE_FEATURE_CODE_VGPU = 1 +NVML_GRID_LICENSE_FEATURE_CODE_NVIDIA_RTX = 2 +NVML_GRID_LICENSE_FEATURE_CODE_VWORKSTATION = 2 # deprecated, use NVML_GRID_LICENSE_FEATURE_CODE_NVIDIA_RTX. +NVML_GRID_LICENSE_FEATURE_CODE_GAMING = 3 +NVML_GRID_LICENSE_FEATURE_CODE_COMPUTE = 4 + +_nvmlGridLicenseExpiryStatus_t = c_uint8 +NVML_GRID_LICENSE_EXPIRY_NOT_AVAILABLE = 0 # Expiry information not available +NVML_GRID_LICENSE_EXPIRY_INVALID = 1 # Invalid expiry or error fetching expiry +NVML_GRID_LICENSE_EXPIRY_VALID = 2 # Valid expiry +NVML_GRID_LICENSE_EXPIRY_NOT_APPLICABLE = 3 # Expiry not applicable +NVML_GRID_LICENSE_EXPIRY_PERMANENT = 4 # Permanent expiry + +_nvmlVgpuCapability_t = c_uint +NVML_VGPU_CAP_NVLINK_P2P = 0 # vGPU P2P over NVLink is supported +NVML_VGPU_CAP_GPUDIRECT = 1 # GPUDirect capability is supported +NVML_VGPU_CAP_MULTI_VGPU_EXCLUSIVE = 2 # vGPU profile cannot be mixed with other vGPU profiles in same VM +NVML_VGPU_CAP_EXCLUSIVE_TYPE = 3 # vGPU profile cannot run on a GPU alongside other profiles of different type +NVML_VGPU_CAP_EXCLUSIVE_SIZE = 4 # vGPU profile cannot run on a GPU alongside other profiles of different size +NVML_VGPU_CAP_COUNT = 5 + +_nvmlVgpuDriverCapability_t = c_uint +NVML_VGPU_DRIVER_CAP_HETEROGENEOUS_MULTI_VGPU = 0 # Supports mixing of different vGPU profiles within one guest VM +NVML_VGPU_DRIVER_CAP_COUNT = 1 + +_nvmlDeviceVgpuCapability_t = c_uint +NVML_DEVICE_VGPU_CAP_FRACTIONAL_MULTI_VGPU = 0 # Fractional vGPU profiles on this GPU can be used in multi-vGPU configurations +NVML_DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_PROFILES = 1 # Supports concurrent execution of timesliced vGPU profiles of differing types +NVML_DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_SIZES = 2 # Supports concurrent execution of timesliced vGPU profiles of differing framebuffer sizes +NVML_DEVICE_VGPU_CAP_READ_DEVICE_BUFFER_BW = 3 # GPU device's read_device_buffer expected bandwidth capacity in megabytes per second +NVML_DEVICE_VGPU_CAP_WRITE_DEVICE_BUFFER_BW = 4 # GPU device's write_device_buffer expected bandwidth capacity in megabytes per second +NVML_DEVICE_VGPU_CAP_COUNT = 5 + +_nvmlVgpuGuestInfoState_t = c_uint +NVML_VGPU_INSTANCE_GUEST_INFO_STATE_UNINITIALIZED = 0 +NVML_VGPU_INSTANCE_GUEST_INFO_STATE_INITIALIZED = 1 + +_nvmlVgpuVmCompatibility_t = c_uint +NVML_VGPU_VM_COMPATIBILITY_NONE = 0x0 +NVML_VGPU_VM_COMPATIBILITY_COLD = 0x1 +NVML_VGPU_VM_COMPATIBILITY_HIBERNATE = 0x2 +NVML_VGPU_VM_COMPATIBILITY_SLEEP = 0x4 +NVML_VGPU_VM_COMPATIBILITY_LIVE = 0x8 + +_nvmlVgpuPgpuCompatibilityLimitCode_t = c_uint +NVML_VGPU_COMPATIBILITY_LIMIT_NONE = 0x0 +NVML_VGPU_COMPATIBILITY_LIMIT_HOST_DRIVER = 0x1 +NVML_VGPU_COMPATIBILITY_LIMIT_GUEST_DRIVER = 0x2 +NVML_VGPU_COMPATIBILITY_LIMIT_GPU = 0x4 +NVML_VGPU_COMPATIBILITY_LIMIT_OTHER = 0x80000000 + +_nvmlHostVgpuMode_t = c_uint +NVML_HOST_VGPU_MODE_NON_SRIOV = 0 +NVML_HOST_VGPU_MODE_SRIOV = 1 + +# GSP firmware +NVML_GSP_FIRMWARE_VERSION_BUF_SIZE = 0x40 + +## Error Checking ## +class NVMLError(Exception): + _valClassMapping = dict() + # List of currently known error codes + _errcode_to_string = { + NVML_ERROR_UNINITIALIZED: "Uninitialized", + NVML_ERROR_INVALID_ARGUMENT: "Invalid Argument", + NVML_ERROR_NOT_SUPPORTED: "Not Supported", + NVML_ERROR_NO_PERMISSION: "Insufficient Permissions", + NVML_ERROR_ALREADY_INITIALIZED: "Already Initialized", + NVML_ERROR_NOT_FOUND: "Not Found", + NVML_ERROR_INSUFFICIENT_SIZE: "Insufficient Size", + NVML_ERROR_INSUFFICIENT_POWER: "Insufficient External Power", + NVML_ERROR_DRIVER_NOT_LOADED: "Driver Not Loaded", + NVML_ERROR_TIMEOUT: "Timeout", + NVML_ERROR_IRQ_ISSUE: "Interrupt Request Issue", + NVML_ERROR_LIBRARY_NOT_FOUND: "NVML Shared Library Not Found", + NVML_ERROR_FUNCTION_NOT_FOUND: "Function Not Found", + NVML_ERROR_CORRUPTED_INFOROM: "Corrupted infoROM", + NVML_ERROR_GPU_IS_LOST: "GPU is lost", + NVML_ERROR_RESET_REQUIRED: "GPU requires restart", + NVML_ERROR_OPERATING_SYSTEM: "The operating system has blocked the request.", + NVML_ERROR_LIB_RM_VERSION_MISMATCH: "RM has detected an NVML/RM version mismatch.", + NVML_ERROR_MEMORY: "Insufficient Memory", + NVML_ERROR_UNKNOWN: "Unknown Error", + } + def __new__(typ, value): + ''' + Maps value to a proper subclass of NVMLError. + See _extractNVMLErrorsAsClasses function for more details + ''' + if typ == NVMLError: + typ = NVMLError._valClassMapping.get(value, typ) + obj = Exception.__new__(typ) + obj.value = value + return obj + def __str__(self): + try: + if self.value not in NVMLError._errcode_to_string: + NVMLError._errcode_to_string[self.value] = str(nvmlErrorString(self.value)) + return NVMLError._errcode_to_string[self.value] + except NVMLError: + return "NVML Error with code %d" % self.value + def __eq__(self, other): + return self.value == other.value + +def nvmlExceptionClass(nvmlErrorCode): + if nvmlErrorCode not in NVMLError._valClassMapping: + raise ValueError('nvmlErrorCode %s is not valid' % nvmlErrorCode) + return NVMLError._valClassMapping[nvmlErrorCode] + +def _extractNVMLErrorsAsClasses(): + ''' + Generates a hierarchy of classes on top of NVMLError class. + + Each NVML Error gets a new NVMLError subclass. This way try,except blocks can filter appropriate + exceptions more easily. + + NVMLError is a parent class. Each NVML_ERROR_* gets it's own subclass. + e.g. NVML_ERROR_ALREADY_INITIALIZED will be turned into NVMLError_AlreadyInitialized + ''' + this_module = sys.modules[__name__] + nvmlErrorsNames = [x for x in dir(this_module) if x.startswith("NVML_ERROR_")] + for err_name in nvmlErrorsNames: + # e.g. Turn NVML_ERROR_ALREADY_INITIALIZED into NVMLError_AlreadyInitialized + class_name = "NVMLError_" + string.capwords(err_name.replace("NVML_ERROR_", ""), "_").replace("_", "") + err_val = getattr(this_module, err_name) + def gen_new(val): + def new(typ): + obj = NVMLError.__new__(typ, val) + return obj + return new + new_error_class = type(class_name, (NVMLError,), {'__new__': gen_new(err_val)}) + new_error_class.__module__ = __name__ + setattr(this_module, class_name, new_error_class) + NVMLError._valClassMapping[err_val] = new_error_class +_extractNVMLErrorsAsClasses() + +def _nvmlCheckReturn(ret): + if (ret != NVML_SUCCESS): + raise NVMLError(ret) + return ret + +## Function access ## +_nvmlGetFunctionPointer_cache = dict() # function pointers are cached to prevent unnecessary libLoadLock locking +def _nvmlGetFunctionPointer(name): + global nvmlLib + + if name in _nvmlGetFunctionPointer_cache: + return _nvmlGetFunctionPointer_cache[name] + + libLoadLock.acquire() + try: + # ensure library was loaded + if (nvmlLib == None): + raise NVMLError(NVML_ERROR_UNINITIALIZED) + try: + _nvmlGetFunctionPointer_cache[name] = getattr(nvmlLib, name) + return _nvmlGetFunctionPointer_cache[name] + except AttributeError: + raise NVMLError(NVML_ERROR_FUNCTION_NOT_FOUND) + finally: + # lock is always freed + libLoadLock.release() + +## Alternative object +# Allows the object to be printed +# Allows mismatched types to be assigned +# - like None when the Structure variant requires c_uint +class nvmlFriendlyObject(object): + def __init__(self, dictionary): + for x in dictionary: + setattr(self, x, dictionary[x]) + def __str__(self): + return self.__dict__.__str__() + +def nvmlStructToFriendlyObject(struct): + d = {} + for x in struct._fields_: + key = x[0] + value = getattr(struct, key) + # only need to convert from bytes if bytes, no need to check python version. + d[key] = value.decode() if isinstance(value, bytes) else value + obj = nvmlFriendlyObject(d) + return obj + +# pack the object so it can be passed to the NVML library +def nvmlFriendlyObjectToStruct(obj, model): + for x in model._fields_: + key = x[0] + value = obj.__dict__[key] + # any c_char_p in python3 needs to be bytes, default encoding works fine. + if sys.version_info >= (3,): + setattr(model, key, value.encode()) + else: + setattr(model, key, value) + return model + +## Unit structures +class struct_c_nvmlUnit_t(Structure): + pass # opaque handle +c_nvmlUnit_t = POINTER(struct_c_nvmlUnit_t) + +class _PrintableStructure(Structure): + """ + Abstract class that produces nicer __str__ output than ctypes.Structure. + e.g. instead of: + >>> print str(obj) + + this class will print + class_name(field_name: formatted_value, field_name: formatted_value) + + _fmt_ dictionary of -> + e.g. class that has _field_ 'hex_value', c_uint could be formatted with + _fmt_ = {"hex_value" : "%08X"} + to produce nicer output. + Default fomratting string for all fields can be set with key "" like: + _fmt_ = {"" : "%d MHz"} # e.g all values are numbers in MHz. + If not set it's assumed to be just "%s" + + Exact format of returned str from this class is subject to change in the future. + """ + _fmt_ = {} + def __str__(self): + result = [] + for x in self._fields_: + key = x[0] + value = getattr(self, key) + fmt = "%s" + if key in self._fmt_: + fmt = self._fmt_[key] + elif "" in self._fmt_: + fmt = self._fmt_[""] + result.append(("%s: " + fmt) % (key, value)) + return self.__class__.__name__ + "(" + ", ".join(result) + ")" + + def __getattribute__(self, name): + res = super(_PrintableStructure, self).__getattribute__(name) + # need to convert bytes to unicode for python3 don't need to for python2 + # Python 2 strings are of both str and bytes + # Python 3 strings are not of type bytes + # ctypes should convert everything to the correct values otherwise + if isinstance(res, bytes): + if isinstance(res, str): + return res + return res.decode() + return res + + def __setattr__(self, name, value): + if isinstance(value, str): + # encoding a python2 string returns the same value, since python2 strings are bytes already + # bytes passed in python3 will be ignored. + value = value.encode() + super(_PrintableStructure, self).__setattr__(name, value) + +class c_nvmlUnitInfo_t(_PrintableStructure): + _fields_ = [ + ('name', c_char * 96), + ('id', c_char * 96), + ('serial', c_char * 96), + ('firmwareVersion', c_char * 96), + ] + +class c_nvmlLedState_t(_PrintableStructure): + _fields_ = [ + ('cause', c_char * 256), + ('color', _nvmlLedColor_t), + ] + +class c_nvmlPSUInfo_t(_PrintableStructure): + _fields_ = [ + ('state', c_char * 256), + ('current', c_uint), + ('voltage', c_uint), + ('power', c_uint), + ] + +class c_nvmlUnitFanInfo_t(_PrintableStructure): + _fields_ = [ + ('speed', c_uint), + ('state', _nvmlFanState_t), + ] + +class c_nvmlUnitFanSpeeds_t(_PrintableStructure): + _fields_ = [ + ('fans', c_nvmlUnitFanInfo_t * 24), + ('count', c_uint) + ] + +## Device structures +class struct_c_nvmlDevice_t(Structure): + pass # opaque handle +c_nvmlDevice_t = POINTER(struct_c_nvmlDevice_t) + +# Legacy pciInfo used for _v1 and _v2 +class nvmlPciInfo_v2_t(_PrintableStructure): + _fields_ = [ + ('busId', c_char * NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE), + ('domain', c_uint), + ('bus', c_uint), + ('device', c_uint), + ('pciDeviceId', c_uint), + + # Added in 2.285 + ('pciSubSystemId', c_uint), + ('reserved0', c_uint), + ('reserved1', c_uint), + ('reserved2', c_uint), + ('reserved3', c_uint), + ] + _fmt_ = { + 'domain' : "0x%04X", + 'bus' : "0x%02X", + 'device' : "0x%02X", + 'pciDeviceId' : "0x%08X", + 'pciSubSystemId' : "0x%08X", + } + +class nvmlPciInfo_t(_PrintableStructure): + _fields_ = [ + # Moved to the new busId location below + ('busIdLegacy', c_char * NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE), + ('domain', c_uint), + ('bus', c_uint), + ('device', c_uint), + ('pciDeviceId', c_uint), + + # Added in 2.285 + ('pciSubSystemId', c_uint), + # New busId replaced the long deprecated and reserved fields with a + # field of the same size in 9.0 + ('busId', c_char * NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE), + ] + _fmt_ = { + 'domain' : "0x%08X", + 'bus' : "0x%02X", + 'device' : "0x%02X", + 'pciDeviceId' : "0x%08X", + 'pciSubSystemId' : "0x%08X", + } + +class c_nvmlExcludedDeviceInfo_t(_PrintableStructure): + _fields_ = [ + ('pci', nvmlPciInfo_t), + ('uuid', c_char * NVML_DEVICE_UUID_BUFFER_SIZE) + ] + +class nvmlNvLinkUtilizationControl_t(_PrintableStructure): + _fields_ = [ + ('units', _nvmlNvLinkUtilizationCountUnits_t), + ('pktfilter', _nvmlNvLinkUtilizationCountPktTypes_t), + ] + +class c_nvmlMemory_t(_PrintableStructure): + _fields_ = [ + ('total', c_ulonglong), + ('free', c_ulonglong), + ('used', c_ulonglong), + ] + _fmt_ = {'': "%d B"} + +class c_nvmlMemory_v2_t(_PrintableStructure): + _fields_ = [ + ('version', c_uint), + ('total', c_ulonglong), + ('reserved', c_ulonglong), + ('free', c_ulonglong), + ('used', c_ulonglong), + ] + _fmt_ = {'': "%d B"} + +nvmlMemory_v2 = 0x02000028 + +class c_nvmlBAR1Memory_t(_PrintableStructure): + _fields_ = [ + ('bar1Total', c_ulonglong), + ('bar1Free', c_ulonglong), + ('bar1Used', c_ulonglong), + ] + _fmt_ = {'': "%d B"} + +class nvmlClkMonFaultInfo_t(Structure): + _fields_ = [("clkApiDomain", c_uint), + ("clkDomainFaultMask", c_uint) + ] + +class nvmlClkMonStatus_t(Structure): + _fields_ = [("bGlobalStatus", c_uint), + ("clkMonListSize", c_uint), + ("clkMonList", nvmlClkMonFaultInfo_t) + ] + +# On Windows with the WDDM driver, usedGpuMemory is reported as None +# Code that processes this structure should check for None, I.E. +# +# if (info.usedGpuMemory == None): +# # TODO handle the error +# pass +# else: +# print("Using %d MiB of memory" % (info.usedGpuMemory / 1024 / 1024)) +# endif +# +# See NVML documentation for more information +class c_nvmlProcessInfo_t(_PrintableStructure): + _fields_ = [ + ('pid', c_uint), + ('usedGpuMemory', c_ulonglong), + ('gpuInstanceId', c_uint), + ('computeInstanceId', c_uint), + ] + _fmt_ = {'usedGpuMemory': "%d B", + } + +class c_nvmlBridgeChipInfo_t(_PrintableStructure): + _fields_ = [ + ('type', _nvmlBridgeChipType_t), + ('fwVersion', c_uint), + ] + +class c_nvmlBridgeChipHierarchy_t(_PrintableStructure): + _fields_ = [ + ('bridgeCount', c_uint), + ('bridgeChipInfo', c_nvmlBridgeChipInfo_t * 128), + ] + +class c_nvmlEccErrorCounts_t(_PrintableStructure): + _fields_ = [ + ('l1Cache', c_ulonglong), + ('l2Cache', c_ulonglong), + ('deviceMemory', c_ulonglong), + ('registerFile', c_ulonglong), + ] + +class c_nvmlUtilization_t(_PrintableStructure): + _fields_ = [ + ('gpu', c_uint), + ('memory', c_uint), + ] + _fmt_ = {'': "%d %%"} + +# Added in 2.285 +class c_nvmlHwbcEntry_t(_PrintableStructure): + _fields_ = [ + ('hwbcId', c_uint), + ('firmwareVersion', c_char * 32), + ] + +class c_nvmlValue_t(Union): + _fields_ = [ + ('dVal', c_double), + ('uiVal', c_uint), + ('ulVal', c_ulong), + ('ullVal', c_ulonglong), + ('sllVal', c_longlong), + ] + +class c_nvmlSample_t(_PrintableStructure): + _fields_ = [ + ('timeStamp', c_ulonglong), + ('sampleValue', c_nvmlValue_t), + ] + +class c_nvmlViolationTime_t(_PrintableStructure): + _fields_ = [ + ('referenceTime', c_ulonglong), + ('violationTime', c_ulonglong), + ] + +class c_nvmlFieldValue_t(_PrintableStructure): + _fields_ = [ + ('fieldId', c_uint32), + ('scopeId', c_uint32), + ('timestamp', c_int64), + ('latencyUsec', c_int64), + ('valueType', _nvmlValueType_t), + ('nvmlReturn', _nvmlReturn_t), + ('value', c_nvmlValue_t) + ] + +class c_nvmlVgpuInstanceUtilizationSample_t(_PrintableStructure): + _fields_ = [ + ('vgpuInstance', _nvmlVgpuInstance_t), + ('timeStamp', c_ulonglong), + ('smUtil', c_nvmlValue_t), + ('memUtil', c_nvmlValue_t), + ('encUtil', c_nvmlValue_t), + ('decUtil', c_nvmlValue_t), + ] + +class c_nvmlVgpuProcessUtilizationSample_t(_PrintableStructure): + _fields_ = [ + ('vgpuInstance', _nvmlVgpuInstance_t), + ('pid', c_uint), + ('processName', c_char * NVML_VGPU_NAME_BUFFER_SIZE), + ('timeStamp', c_ulonglong), + ('smUtil', c_uint), + ('memUtil', c_uint), + ('encUtil', c_uint), + ('decUtil', c_uint), + ] + +class c_nvmlVgpuLicenseExpiry_t(_PrintableStructure): + _fields_ = [ + ('year', c_uint32), + ('month', c_uint16), + ('day', c_uint16), + ('hour', c_uint16), + ('min', c_uint16), + ('sec', c_uint16), + ('status', c_uint8), + ] + +NVML_GRID_LICENSE_STATE_UNKNOWN = 0 +NVML_GRID_LICENSE_STATE_UNINITIALIZED = 1 +NVML_GRID_LICENSE_STATE_UNLICENSED_UNRESTRICTED = 2 +NVML_GRID_LICENSE_STATE_UNLICENSED_RESTRICTED = 3 +NVML_GRID_LICENSE_STATE_UNLICENSED = 4 +NVML_GRID_LICENSE_STATE_LICENSED = 5 + +class c_nvmlVgpuLicenseInfo_t(_PrintableStructure): + _fields_ = [ + ('isLicensed', c_uint8), + ('licenseExpiry', c_nvmlVgpuLicenseExpiry_t), + ('currentState', c_uint), + ] + +class c_nvmlEncoderSession_t(_PrintableStructure): + _fields_ = [ + ('sessionId', c_uint), + ('pid', c_uint), + ('vgpuInstance', _nvmlVgpuInstance_t), + ('codecType', c_uint), + ('hResolution', c_uint), + ('vResolution', c_uint), + ('averageFps', c_uint), + ('encodeLatency', c_uint), + ] + +class c_nvmlProcessUtilizationSample_t(_PrintableStructure): + _fields_ = [ + ('pid', c_uint), + ('timeStamp', c_ulonglong), + ('smUtil', c_uint), + ('memUtil', c_uint), + ('encUtil', c_uint), + ('decUtil', c_uint), + ] + +class c_nvmlGridLicenseExpiry_t(_PrintableStructure): + _fields_ = [ + ('year', c_uint32), + ('month', c_uint16), + ('day', c_uint16), + ('hour', c_uint16), + ('min', c_uint16), + ('sec', c_uint16), + ('status', c_uint8), + ] + +class c_nvmlGridLicensableFeature_v4_t(_PrintableStructure): + _fields_ = [ + ('featureCode', _nvmlGridLicenseFeatureCode_t), + ('featureState', c_uint), + ('licenseInfo', c_char * NVML_GRID_LICENSE_BUFFER_SIZE), + ('productName', c_char * NVML_GRID_LICENSE_BUFFER_SIZE), + ('featureEnabled', c_uint), + ('licenseExpiry', c_nvmlGridLicenseExpiry_t), + ] + +class c_nvmlGridLicensableFeatures_v4_t(_PrintableStructure): + _fields_ = [ + ('isGridLicenseSupported', c_int), + ('licensableFeaturesCount', c_uint), + ('gridLicensableFeatures', c_nvmlGridLicensableFeature_v4_t * NVML_GRID_LICENSE_FEATURE_MAX_COUNT), + ] + +class c_nvmlGridLicensableFeature_v3_t(_PrintableStructure): + _fields_ = [ + ('featureCode', _nvmlGridLicenseFeatureCode_t), + ('featureState', c_uint), + ('licenseInfo', c_char * NVML_GRID_LICENSE_BUFFER_SIZE), + ('productName', c_char * NVML_GRID_LICENSE_BUFFER_SIZE), + ('featureEnabled', c_uint), + ] + +class c_nvmlGridLicensableFeatures_v3_t(_PrintableStructure): + _fields_ = [ + ('isGridLicenseSupported', c_int), + ('licensableFeaturesCount', c_uint), + ('gridLicensableFeatures', c_nvmlGridLicensableFeature_v3_t * NVML_GRID_LICENSE_FEATURE_MAX_COUNT), + ] + +class c_nvmlGridLicensableFeature_v2_t(_PrintableStructure): + _fields_ = [ + ('featureCode', _nvmlGridLicenseFeatureCode_t), + ('featureState', c_uint), + ('licenseInfo', c_char * NVML_GRID_LICENSE_BUFFER_SIZE), + ('productName', c_char * NVML_GRID_LICENSE_BUFFER_SIZE), + ] + +class c_nvmlGridLicensableFeatures_v2_t(_PrintableStructure): + _fields_ = [ + ('isGridLicenseSupported', c_int), + ('licensableFeaturesCount', c_uint), + ('gridLicensableFeatures', c_nvmlGridLicensableFeature_v2_t * NVML_GRID_LICENSE_FEATURE_MAX_COUNT), + ] + +class c_nvmlGridLicensableFeature_t(_PrintableStructure): + _fields_ = [ + ('featureCode', _nvmlGridLicenseFeatureCode_t), + ('featureState', c_uint), + ('licenseInfo', c_char * NVML_GRID_LICENSE_BUFFER_SIZE), + ] + +class c_nvmlGridLicensableFeatures_t(_PrintableStructure): + _fields_ = [ + ('isGridLicenseSupported', c_int), + ('licensableFeaturesCount', c_uint), + ('gridLicensableFeatures', c_nvmlGridLicensableFeature_t * NVML_GRID_LICENSE_FEATURE_MAX_COUNT), + ] + +## Event structures +class struct_c_nvmlEventSet_t(Structure): + pass # opaque handle +c_nvmlEventSet_t = POINTER(struct_c_nvmlEventSet_t) + +nvmlEventTypeSingleBitEccError = 0x0000000000000001 +nvmlEventTypeDoubleBitEccError = 0x0000000000000002 +nvmlEventTypePState = 0x0000000000000004 +nvmlEventTypeXidCriticalError = 0x0000000000000008 +nvmlEventTypeClock = 0x0000000000000010 +nvmlEventTypePowerSourceChange = 0x0000000000000080 +nvmlEventMigConfigChange = 0x0000000000000100 +nvmlEventTypeNone = 0x0000000000000000 +nvmlEventTypeAll = ( + nvmlEventTypeNone + | nvmlEventTypeSingleBitEccError + | nvmlEventTypeDoubleBitEccError + | nvmlEventTypePState + | nvmlEventTypeClock + | nvmlEventTypePowerSourceChange + | nvmlEventTypeXidCriticalError + | nvmlEventMigConfigChange + ) + +## Clock Throttle Reasons defines +nvmlClocksThrottleReasonGpuIdle = 0x0000000000000001 +nvmlClocksThrottleReasonApplicationsClocksSetting = 0x0000000000000002 +nvmlClocksThrottleReasonUserDefinedClocks = nvmlClocksThrottleReasonApplicationsClocksSetting # deprecated, use nvmlClocksThrottleReasonApplicationsClocksSetting +nvmlClocksThrottleReasonSwPowerCap = 0x0000000000000004 +nvmlClocksThrottleReasonHwSlowdown = 0x0000000000000008 +nvmlClocksThrottleReasonSyncBoost = 0x0000000000000010 +nvmlClocksThrottleReasonSwThermalSlowdown = 0x0000000000000020 +nvmlClocksThrottleReasonHwThermalSlowdown = 0x0000000000000040 +nvmlClocksThrottleReasonHwPowerBrakeSlowdown = 0x0000000000000080 +nvmlClocksThrottleReasonDisplayClockSetting = 0x0000000000000100 +nvmlClocksThrottleReasonNone = 0x0000000000000000 +nvmlClocksThrottleReasonAll = ( + nvmlClocksThrottleReasonNone | + nvmlClocksThrottleReasonGpuIdle | + nvmlClocksThrottleReasonApplicationsClocksSetting | + nvmlClocksThrottleReasonSwPowerCap | + nvmlClocksThrottleReasonHwSlowdown | + nvmlClocksThrottleReasonSyncBoost | + nvmlClocksThrottleReasonSwThermalSlowdown | + nvmlClocksThrottleReasonHwThermalSlowdown | + nvmlClocksThrottleReasonHwPowerBrakeSlowdown | + nvmlClocksThrottleReasonDisplayClockSetting + ) + +class c_nvmlEventData_t(_PrintableStructure): + _fields_ = [ + ('device', c_nvmlDevice_t), + ('eventType', c_ulonglong), + ('eventData', c_ulonglong), + ('gpuInstanceId', c_uint), + ('computeInstanceId', c_uint) + ] + _fmt_ = {'eventType': "0x%08X"} + +class c_nvmlAccountingStats_t(_PrintableStructure): + _fields_ = [ + ('gpuUtilization', c_uint), + ('memoryUtilization', c_uint), + ('maxMemoryUsage', c_ulonglong), + ('time', c_ulonglong), + ('startTime', c_ulonglong), + ('isRunning', c_uint), + ('reserved', c_uint * 5) + ] + +class c_nvmlVgpuVersion_t(Structure): + _fields_ = [("minVersion", c_uint), + ("maxVersion", c_uint) + ] + +class c_nvmlVgpuMetadata_t(_PrintableStructure): + _fields_ = [("version", c_uint), + ("revision", c_uint), + ("guestInfoState", _nvmlVgpuGuestInfoState_t), + ("guestDriverVersion", c_char * NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE), + ("hostDriverVersion", c_char * NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE), + ("reserved", c_uint * 6), + ("vgpuVirtualizationCaps", c_uint), + ("guestVgpuVersion", c_uint), + ("opaqueDataSize", c_uint), + ("opaqueData", c_char * NVML_VGPU_METADATA_OPAQUE_DATA_SIZE) + ] + +class c_nvmlVgpuPgpuMetadata_t(_PrintableStructure): + _fields_ = [("version", c_uint), + ("revision", c_uint), + ("hostDriverVersion", c_char * NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE), + ("pgpuVirtualizationCaps", c_uint), + ("reserved", c_uint * 5), + ("hostSupportedVgpuRange", c_nvmlVgpuVersion_t), + ("opaqueDataSize", c_uint), + ("opaqueData", c_char * NVML_VGPU_PGPU_METADATA_OPAQUE_DATA_SIZE) + ] + +class c_nvmlVgpuPgpuCompatibility_t(Structure): + _fields_ = [("vgpuVmCompatibility", _nvmlVgpuVmCompatibility_t), + ("compatibilityLimitCode", _nvmlVgpuPgpuCompatibilityLimitCode_t) + ] + +## vGPU scheduler policy defines +NVML_VGPU_SCHEDULER_POLICY_UNKNOWN = 0 +NVML_VGPU_SCHEDULER_POLICY_BEST_EFFORT = 1 +NVML_VGPU_SCHEDULER_POLICY_EQUAL_SHARE = 2 +NVML_VGPU_SCHEDULER_POLICY_FIXED_SHARE = 3 + +## Supported vGPU scheduler policy count +NVML_SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT = 3 + +NVML_SCHEDULER_SW_MAX_LOG_ENTRIES = 200 + +class c_nvmlVgpuSchedDataWithARR_t(_PrintableStructure): + _fields_ = [ + ('avgFactor', c_uint), + ('timeslice', c_uint), + ] + +class c_nvmlVgpuSchedData_t(_PrintableStructure): + _fields_ = [ + ('timeslice', c_uint), + ] + +class c_nvmlVgpuSchedulerParams_t(Union): + _fields_ = [ + ('vgpuSchedDataWithARR', c_nvmlVgpuSchedDataWithARR_t), + ('vgpuSchedData', c_nvmlVgpuSchedData_t), + ] + +class c_nvmlVgpuSchedulerLogEntry_t(_PrintableStructure): + _fields_ = [ + ('timestamp', c_ulonglong), + ('timeRunTotal', c_ulonglong), + ('timeRun', c_ulonglong), + ('swRunlistId', c_uint), + ('targetTimeSlice', c_ulonglong), + ('cumulativePreemptionTime', c_ulonglong), + ] + +class c_nvmlVgpuSchedulerLog_t(_PrintableStructure): + _fields_ = [ + ('engineId', c_uint), + ('schedulerPolicy', c_uint), + ('isEnabledARR', c_uint), + ('schedulerParams', c_nvmlVgpuSchedulerParams_t), + ('entriesCount', c_uint), + ('logEntries', c_nvmlVgpuSchedulerLogEntry_t * NVML_SCHEDULER_SW_MAX_LOG_ENTRIES), + ] + +class c_nvmlVgpuSchedulerGetState_t(_PrintableStructure): + _fields_ = [ + ('schedulerPolicy', c_uint), + ('isEnabledARR', c_uint), + ('schedulerParams', c_nvmlVgpuSchedulerParams_t), + ] + +class c_nvmlVgpuSchedSetDataWithARR_t(_PrintableStructure): + _fields_ = [ + ('avgFactor', c_uint), + ('frequency', c_uint), + ] + +class c_nvmlVgpuSchedSetData_t(_PrintableStructure): + _fields_ = [ + ('timeslice', c_uint), + ] + +class c_nvmlVgpuSchedulerCapabilities_t(_PrintableStructure): + _fields_ = [ + ('supportedSchedulers', c_uint * NVML_SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT), + ('maxTimeslice', c_uint), + ('minTimeslice', c_uint), + ('isArrModeSupported', c_uint), + ('maxFrequencyForARR', c_uint), + ('minFrequencyForARR', c_uint), + ('maxAvgFactorForARR', c_uint), + ('minAvgFactorForARR', c_uint), + ] + +class c_nvmlFBCStats_t(Structure): + _fields_ = [("sessionsCount", c_uint), + ("averageFPS", c_uint), + ("averageLatency", c_uint) + ] + +class c_nvmlFBCSession_t(_PrintableStructure): + _fields_ = [ + ('sessionId', c_uint), + ('pid', c_uint), + ('vgpuInstance', _nvmlVgpuInstance_t), + ('displayOrdinal', c_uint), + ('sessionType', c_uint), + ('sessionFlags', c_uint), + ('hMaxResolution', c_uint), + ('vMaxResolution', c_uint), + ('hResolution', c_uint), + ('vResolution', c_uint), + ('averageFPS', c_uint), + ('averageLatency', c_uint), + ] + +NVML_DEVICE_MIG_DISABLE = 0x0 +NVML_DEVICE_MIG_ENABLE = 0x1 + +NVML_GPU_INSTANCE_PROFILE_1_SLICE = 0x0 +NVML_GPU_INSTANCE_PROFILE_2_SLICE = 0x1 +NVML_GPU_INSTANCE_PROFILE_3_SLICE = 0x2 +NVML_GPU_INSTANCE_PROFILE_4_SLICE = 0x3 +NVML_GPU_INSTANCE_PROFILE_7_SLICE = 0x4 +NVML_GPU_INSTANCE_PROFILE_8_SLICE = 0x5 +NVML_GPU_INSTANCE_PROFILE_6_SLICE = 0x6 +NVML_GPU_INSTANCE_PROFILE_1_SLICE_REV1 = 0x7 +NVML_GPU_INSTANCE_PROFILE_2_SLICE_REV1 = 0x8 +NVML_GPU_INSTANCE_PROFILE_1_SLICE_REV2 = 0x9 +NVML_GPU_INSTANCE_PROFILE_COUNT = 0xA + +class c_nvmlGpuInstancePlacement_t(Structure): + _fields_ = [("start", c_uint), + ("size", c_uint) + ] + +class c_nvmlGpuInstanceProfileInfo_t(Structure): + _fields_ = [("id", c_uint), + ("isP2pSupported", c_uint), + ("sliceCount", c_uint), + ("instanceCount", c_uint), + ("multiprocessorCount", c_uint), + ("copyEngineCount", c_uint), + ("decoderCount", c_uint), + ("encoderCount", c_uint), + ("jpegCount", c_uint), + ("ofaCount", c_uint), + ("memorySizeMB", c_ulonglong), + ] + +nvmlGpuInstanceProfileInfo_v2 = 0x02000098 + +class c_nvmlGpuInstanceProfileInfo_v2_t(_PrintableStructure): + _fields_ = [("version", c_uint), + ("id", c_uint), + ("isP2pSupported", c_uint), + ("sliceCount", c_uint), + ("instanceCount", c_uint), + ("multiprocessorCount", c_uint), + ("copyEngineCount", c_uint), + ("decoderCount", c_uint), + ("encoderCount", c_uint), + ("jpegCount", c_uint), + ("ofaCount", c_uint), + ("memorySizeMB", c_ulonglong), + ("name", c_char * NVML_DEVICE_NAME_V2_BUFFER_SIZE) + ] + + def __init__(self): + super(c_nvmlGpuInstanceProfileInfo_v2_t, self).__init__(version=nvmlGpuInstanceProfileInfo_v2) + +class c_nvmlGpuInstanceInfo_t(Structure): + _fields_ = [("device", c_nvmlDevice_t), + ("id", c_uint), + ("profileId", c_uint), + ("placement", c_nvmlGpuInstancePlacement_t) + ] + +class struct_c_nvmlGpuInstance_t(Structure): + pass # opaque handle +c_nvmlGpuInstance_t = POINTER(struct_c_nvmlGpuInstance_t) + +NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE = 0x0 +NVML_COMPUTE_INSTANCE_PROFILE_2_SLICE = 0x1 +NVML_COMPUTE_INSTANCE_PROFILE_3_SLICE = 0x2 +NVML_COMPUTE_INSTANCE_PROFILE_4_SLICE = 0x3 +NVML_COMPUTE_INSTANCE_PROFILE_7_SLICE = 0x4 +NVML_COMPUTE_INSTANCE_PROFILE_8_SLICE = 0x5 +NVML_COMPUTE_INSTANCE_PROFILE_6_SLICE = 0x6 +NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE_REV1 = 0x7 +NVML_COMPUTE_INSTANCE_PROFILE_COUNT = 0x8 + +NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_SHARED = 0x0 +NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT = 0x1 + +class c_nvmlComputeInstancePlacement_t(Structure): + _fields_ = [("start", c_uint), + ("size", c_uint) + ] + +class c_nvmlComputeInstanceProfileInfo_t(Structure): + _fields_ = [("id", c_uint), + ("sliceCount", c_uint), + ("instanceCount", c_uint), + ("multiprocessorCount", c_uint), + ("sharedCopyEngineCount", c_uint), + ("sharedDecoderCount", c_uint), + ("sharedEncoderCount", c_uint), + ("sharedJpegCount", c_uint), + ("sharedOfaCount", c_uint) + ] + +nvmlComputeInstanceProfileInfo_v2 = 0x02000088 + +class c_nvmlComputeInstanceProfileInfo_v2_t(_PrintableStructure): + _fields_ = [("version", c_uint), + ("id", c_uint), + ("sliceCount", c_uint), + ("instanceCount", c_uint), + ("multiprocessorCount", c_uint), + ("sharedCopyEngineCount", c_uint), + ("sharedDecoderCount", c_uint), + ("sharedEncoderCount", c_uint), + ("sharedJpegCount", c_uint), + ("sharedOfaCount", c_uint), + ("name", c_char * NVML_DEVICE_NAME_V2_BUFFER_SIZE) + ] + + def __init__(self): + super(c_nvmlComputeInstanceProfileInfo_v2_t, self).__init__(version=nvmlComputeInstanceProfileInfo_v2) + +class c_nvmlComputeInstanceInfo_t(Structure): + _fields_ = [("device", c_nvmlDevice_t), + ("gpuInstance", c_nvmlGpuInstance_t), + ("id", c_uint), + ("profileId", c_uint), + ("placement", c_nvmlComputeInstancePlacement_t) + ] + +NVML_MAX_GPU_UTILIZATIONS = 8 +NVML_GPU_UTILIZATION_DOMAIN_GPU = 0 +NVML_GPU_UTILIZATION_DOMAIN_FB = 1 +NVML_GPU_UTILIZATION_DOMAIN_VID = 2 +NVML_GPU_UTILIZATION_DOMAIN_BUS = 3 +class c_nvmlGpuDynamicPstatesUtilization_t(Structure): + _fields_ = [("bIsPresent", c_uint, 1), + ("percentage", c_uint), + ("incThreshold", c_uint), + ("decThreshold", c_uint)] +class c_nvmlGpuDynamicPstatesInfo_t(Structure): + _fields_ = [("flags", c_uint), + ("utilization", c_nvmlGpuDynamicPstatesUtilization_t * NVML_MAX_GPU_UTILIZATIONS)] + +NVML_MAX_THERMAL_SENSORS_PER_GPU = 3 + +NVML_THERMAL_TARGET_NONE = 0 +NVML_THERMAL_TARGET_GPU = 1 +NVML_THERMAL_TARGET_MEMORY = 2 +NVML_THERMAL_TARGET_POWER_SUPPLY = 4 +NVML_THERMAL_TARGET_BOARD = 8 +NVML_THERMAL_TARGET_VCD_BOARD = 9 +NVML_THERMAL_TARGET_VCD_INLET = 10 +NVML_THERMAL_TARGET_VCD_OUTLET = 11 +NVML_THERMAL_TARGET_ALL = 15 +NVML_THERMAL_TARGET_UNKNOWN = -1 + +NVML_THERMAL_CONTROLLER_NONE = 0 +NVML_THERMAL_CONTROLLER_GPU_INTERNAL = 1 +NVML_THERMAL_CONTROLLER_ADM1032 = 2 +NVML_THERMAL_CONTROLLER_ADT7461 = 3 +NVML_THERMAL_CONTROLLER_MAX6649 = 4 +NVML_THERMAL_CONTROLLER_MAX1617 = 5 +NVML_THERMAL_CONTROLLER_LM99 = 6 +NVML_THERMAL_CONTROLLER_LM89 = 7 +NVML_THERMAL_CONTROLLER_LM64 = 8 +NVML_THERMAL_CONTROLLER_G781 = 9 +NVML_THERMAL_CONTROLLER_ADT7473 = 10 +NVML_THERMAL_CONTROLLER_SBMAX6649 = 11 +NVML_THERMAL_CONTROLLER_VBIOSEVT = 12 +NVML_THERMAL_CONTROLLER_OS = 13 +NVML_THERMAL_CONTROLLER_NVSYSCON_CANOAS = 14 +NVML_THERMAL_CONTROLLER_NVSYSCON_E551 = 15 +NVML_THERMAL_CONTROLLER_MAX6649R = 16 +NVML_THERMAL_CONTROLLER_ADT7473S = 17 +NVML_THERMAL_CONTROLLER_UNKNOWN = -1 + +class c_nvmlGpuThermalSensor_t(Structure): + _fields_ = [("controller", c_int), + ("defaultMinTemp", c_int), + ("defaultMaxTemp", c_int), + ("currentTemp", c_int), + ("target", c_int)] +class c_nvmlGpuThermalSettings_t(Structure): + _fields_ = [("count", c_uint), + ("sensor", c_nvmlGpuThermalSensor_t * NVML_MAX_THERMAL_SENSORS_PER_GPU)] + +class struct_c_nvmlComputeInstance_t(Structure): + pass # opaque handle +c_nvmlComputeInstance_t = POINTER(struct_c_nvmlComputeInstance_t) + +class c_nvmlDeviceAttributes(Structure): + _fields_ = [("multiprocessorCount", c_uint), + ("sharedCopyEngineCount", c_uint), + ("sharedDecoderCount", c_uint), + ("sharedEncoderCount", c_uint), + ("sharedJpegCount", c_uint), + ("sharedOfaCount", c_uint), + ("gpuInstanceSliceCount", c_uint), + ("computeInstanceSliceCount", c_uint), + ("memorySizeMB", c_ulonglong), + ] + +class c_nvmlRowRemapperHistogramValues(Structure): + _fields_ = [("max", c_uint), + ("high", c_uint), + ("partial", c_uint), + ("low", c_uint), + ("none", c_uint) + ] + + +## string/bytes conversion for ease of use +def convertStrBytes(func): + ''' + In python 3, strings are unicode instead of bytes, and need to be converted for ctypes + Args from caller: (1, 'string', <__main__.c_nvmlDevice_t at 0xFFFFFFFF>) + Args passed to function: (1, b'string', <__main__.c_nvmlDevice_t at 0xFFFFFFFF)> + ---- + Returned from function: b'returned string' + Returned to caller: 'returned string' + ''' + @wraps(func) + def wrapper(*args, **kwargs): + # encoding a str returns bytes in python 2 and 3 + args = [arg.encode() if isinstance(arg, str) else arg for arg in args] + res = func(*args, **kwargs) + # In python 2, str and bytes are the same + # In python 3, str is unicode and should be decoded. + # Ctypes handles most conversions, this only effects c_char and char arrays. + if isinstance(res, bytes): + if isinstance(res, str): + return res + return res.decode() + return res + + if sys.version_info >= (3,): + return wrapper + return func + +## C function wrappers ## +def nvmlInitWithFlags(flags): + _LoadNvmlLibrary() + + # + # Initialize the library + # + fn = _nvmlGetFunctionPointer("nvmlInitWithFlags") + ret = fn(flags) + _nvmlCheckReturn(ret) + + # Atomically update refcount + global _nvmlLib_refcount + libLoadLock.acquire() + _nvmlLib_refcount += 1 + libLoadLock.release() + return None + +def nvmlInit(): + nvmlInitWithFlags(0) + return None + +def _LoadNvmlLibrary(): + ''' + Load the library if it isn't loaded already + ''' + global nvmlLib + + if (nvmlLib == None): + # lock to ensure only one caller loads the library + libLoadLock.acquire() + + try: + # ensure the library still isn't loaded + if (nvmlLib == None): + try: + if (sys.platform[:3] == "win"): + # cdecl calling convention + try: + # Check for nvml.dll in System32 first for DCH drivers + nvmlLib = CDLL(os.path.join(os.getenv("WINDIR", "C:/Windows"), "System32/nvml.dll")) + except OSError as ose: + # If nvml.dll is not found in System32, it should be in ProgramFiles + # load nvml.dll from %ProgramFiles%/NVIDIA Corporation/NVSMI/nvml.dll + nvmlLib = CDLL(os.path.join(os.getenv("ProgramFiles", "C:/Program Files"), "NVIDIA Corporation/NVSMI/nvml.dll")) + else: + # assume linux + nvmlLib = CDLL("libnvidia-ml.so.1") + except OSError as ose: + _nvmlCheckReturn(NVML_ERROR_LIBRARY_NOT_FOUND) + if (nvmlLib == None): + _nvmlCheckReturn(NVML_ERROR_LIBRARY_NOT_FOUND) + finally: + # lock is always freed + libLoadLock.release() + +def nvmlShutdown(): + # + # Leave the library loaded, but shutdown the interface + # + fn = _nvmlGetFunctionPointer("nvmlShutdown") + ret = fn() + _nvmlCheckReturn(ret) + + # Atomically update refcount + global _nvmlLib_refcount + libLoadLock.acquire() + if (0 < _nvmlLib_refcount): + _nvmlLib_refcount -= 1 + libLoadLock.release() + return None + +# Added in 2.285 +@convertStrBytes +def nvmlErrorString(result): + fn = _nvmlGetFunctionPointer("nvmlErrorString") + fn.restype = c_char_p # otherwise return is an int + ret = fn(result) + return ret + +# Added in 2.285 +@convertStrBytes +def nvmlSystemGetNVMLVersion(): + c_version = create_string_buffer(NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlSystemGetNVMLVersion") + ret = fn(c_version, c_uint(NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE)) + _nvmlCheckReturn(ret) + return c_version.value + +def nvmlSystemGetCudaDriverVersion(): + c_cuda_version = c_int() + fn = _nvmlGetFunctionPointer("nvmlSystemGetCudaDriverVersion") + ret = fn(byref(c_cuda_version)) + _nvmlCheckReturn(ret) + return c_cuda_version.value + +def nvmlSystemGetCudaDriverVersion_v2(): + c_cuda_version = c_int() + fn = _nvmlGetFunctionPointer("nvmlSystemGetCudaDriverVersion_v2") + ret = fn(byref(c_cuda_version)) + _nvmlCheckReturn(ret) + return c_cuda_version.value + +# Added in 2.285 +@convertStrBytes +def nvmlSystemGetProcessName(pid): + c_name = create_string_buffer(1024) + fn = _nvmlGetFunctionPointer("nvmlSystemGetProcessName") + ret = fn(c_uint(pid), c_name, c_uint(1024)) + _nvmlCheckReturn(ret) + return c_name.value + +@convertStrBytes +def nvmlSystemGetDriverVersion(): + c_version = create_string_buffer(NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlSystemGetDriverVersion") + ret = fn(c_version, c_uint(NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE)) + _nvmlCheckReturn(ret) + return c_version.value + +# Added in 2.285 +def nvmlSystemGetHicVersion(): + c_count = c_uint(0) + hics = None + fn = _nvmlGetFunctionPointer("nvmlSystemGetHicVersion") + + # get the count + ret = fn(byref(c_count), None) + + # this should only fail with insufficient size + if ((ret != NVML_SUCCESS) and + (ret != NVML_ERROR_INSUFFICIENT_SIZE)): + raise NVMLError(ret) + + # If there are no hics + if (c_count.value == 0): + return [] + + hic_array = c_nvmlHwbcEntry_t * c_count.value + hics = hic_array() + ret = fn(byref(c_count), hics) + _nvmlCheckReturn(ret) + return hics + +## Unit get functions +def nvmlUnitGetCount(): + c_count = c_uint() + fn = _nvmlGetFunctionPointer("nvmlUnitGetCount") + ret = fn(byref(c_count)) + _nvmlCheckReturn(ret) + return c_count.value + +def nvmlUnitGetHandleByIndex(index): + c_index = c_uint(index) + unit = c_nvmlUnit_t() + fn = _nvmlGetFunctionPointer("nvmlUnitGetHandleByIndex") + ret = fn(c_index, byref(unit)) + _nvmlCheckReturn(ret) + return unit + +def nvmlUnitGetUnitInfo(unit): + c_info = c_nvmlUnitInfo_t() + fn = _nvmlGetFunctionPointer("nvmlUnitGetUnitInfo") + ret = fn(unit, byref(c_info)) + _nvmlCheckReturn(ret) + return c_info + +def nvmlUnitGetLedState(unit): + c_state = c_nvmlLedState_t() + fn = _nvmlGetFunctionPointer("nvmlUnitGetLedState") + ret = fn(unit, byref(c_state)) + _nvmlCheckReturn(ret) + return c_state + +def nvmlUnitGetPsuInfo(unit): + c_info = c_nvmlPSUInfo_t() + fn = _nvmlGetFunctionPointer("nvmlUnitGetPsuInfo") + ret = fn(unit, byref(c_info)) + _nvmlCheckReturn(ret) + return c_info + +def nvmlUnitGetTemperature(unit, type): + c_temp = c_uint() + fn = _nvmlGetFunctionPointer("nvmlUnitGetTemperature") + ret = fn(unit, c_uint(type), byref(c_temp)) + _nvmlCheckReturn(ret) + return c_temp.value + +def nvmlUnitGetFanSpeedInfo(unit): + c_speeds = c_nvmlUnitFanSpeeds_t() + fn = _nvmlGetFunctionPointer("nvmlUnitGetFanSpeedInfo") + ret = fn(unit, byref(c_speeds)) + _nvmlCheckReturn(ret) + return c_speeds + +# added to API +def nvmlUnitGetDeviceCount(unit): + c_count = c_uint(0) + # query the unit to determine device count + fn = _nvmlGetFunctionPointer("nvmlUnitGetDevices") + ret = fn(unit, byref(c_count), None) + if (ret == NVML_ERROR_INSUFFICIENT_SIZE): + ret = NVML_SUCCESS + _nvmlCheckReturn(ret) + return c_count.value + +def nvmlUnitGetDevices(unit): + c_count = c_uint(nvmlUnitGetDeviceCount(unit)) + device_array = c_nvmlDevice_t * c_count.value + c_devices = device_array() + fn = _nvmlGetFunctionPointer("nvmlUnitGetDevices") + ret = fn(unit, byref(c_count), c_devices) + _nvmlCheckReturn(ret) + return c_devices + +## Device get functions +def nvmlDeviceGetCount(): + c_count = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetCount_v2") + ret = fn(byref(c_count)) + _nvmlCheckReturn(ret) + return c_count.value + +def nvmlDeviceGetHandleByIndex(index): + c_index = c_uint(index) + device = c_nvmlDevice_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetHandleByIndex_v2") + ret = fn(c_index, byref(device)) + _nvmlCheckReturn(ret) + return device + +@convertStrBytes +def nvmlDeviceGetHandleBySerial(serial): + c_serial = c_char_p(serial) + device = c_nvmlDevice_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetHandleBySerial") + ret = fn(c_serial, byref(device)) + _nvmlCheckReturn(ret) + return device + +@convertStrBytes +def nvmlDeviceGetHandleByUUID(uuid): + c_uuid = c_char_p(uuid) + device = c_nvmlDevice_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetHandleByUUID") + ret = fn(c_uuid, byref(device)) + _nvmlCheckReturn(ret) + return device + +@convertStrBytes +def nvmlDeviceGetHandleByPciBusId(pciBusId): + c_busId = c_char_p(pciBusId) + device = c_nvmlDevice_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetHandleByPciBusId_v2") + ret = fn(c_busId, byref(device)) + _nvmlCheckReturn(ret) + return device + +@convertStrBytes +def nvmlDeviceGetName(handle): + c_name = create_string_buffer(NVML_DEVICE_NAME_V2_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetName") + ret = fn(handle, c_name, c_uint(NVML_DEVICE_NAME_V2_BUFFER_SIZE)) + _nvmlCheckReturn(ret) + return c_name.value + +def nvmlDeviceGetBoardId(handle): + c_id = c_uint(); + fn = _nvmlGetFunctionPointer("nvmlDeviceGetBoardId") + ret = fn(handle, byref(c_id)) + _nvmlCheckReturn(ret) + return c_id.value + +def nvmlDeviceGetMultiGpuBoard(handle): + c_multiGpu = c_uint(); + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMultiGpuBoard") + ret = fn(handle, byref(c_multiGpu)) + _nvmlCheckReturn(ret) + return c_multiGpu.value + +def nvmlDeviceGetBrand(handle): + c_type = _nvmlBrandType_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetBrand") + ret = fn(handle, byref(c_type)) + _nvmlCheckReturn(ret) + return c_type.value + +@convertStrBytes +def nvmlDeviceGetBoardPartNumber(handle): + c_part_number = create_string_buffer(NVML_DEVICE_PART_NUMBER_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetBoardPartNumber") + ret = fn(handle, c_part_number, c_uint(NVML_DEVICE_PART_NUMBER_BUFFER_SIZE)) + _nvmlCheckReturn(ret) + return c_part_number.value + +@convertStrBytes +def nvmlDeviceGetSerial(handle): + c_serial = create_string_buffer(NVML_DEVICE_SERIAL_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetSerial") + ret = fn(handle, c_serial, c_uint(NVML_DEVICE_SERIAL_BUFFER_SIZE)) + _nvmlCheckReturn(ret) + return c_serial.value + +def nvmlDeviceGetMemoryAffinity(handle, nodeSetSize, scope): + affinity_array = c_ulonglong * nodeSetSize + c_affinity = affinity_array() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMemoryAffinity") + ret = fn(handle, nodeSetSize, byref(c_affinity), _nvmlAffinityScope_t(scope)) + _nvmlCheckReturn(ret) + return c_affinity + +def nvmlDeviceGetCpuAffinityWithinScope(handle, cpuSetSize, scope): + affinity_array = c_ulonglong * cpuSetSize + c_affinity = affinity_array() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetCpuAffinityWithinScope") + ret = fn(handle, cpuSetSize, byref(c_affinity), _nvmlAffinityScope_t(scope)) + _nvmlCheckReturn(ret) + return c_affinity + +def nvmlDeviceGetCpuAffinity(handle, cpuSetSize): + affinity_array = c_ulonglong * cpuSetSize + c_affinity = affinity_array() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetCpuAffinity") + ret = fn(handle, cpuSetSize, byref(c_affinity)) + _nvmlCheckReturn(ret) + return c_affinity + +def nvmlDeviceSetCpuAffinity(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetCpuAffinity") + ret = fn(handle) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceClearCpuAffinity(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceClearCpuAffinity") + ret = fn(handle) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceGetMinorNumber(handle): + c_minor_number = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMinorNumber") + ret = fn(handle, byref(c_minor_number)) + _nvmlCheckReturn(ret) + return c_minor_number.value + +@convertStrBytes +def nvmlDeviceGetUUID(handle): + c_uuid = create_string_buffer(NVML_DEVICE_UUID_V2_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetUUID") + ret = fn(handle, c_uuid, c_uint(NVML_DEVICE_UUID_V2_BUFFER_SIZE)) + _nvmlCheckReturn(ret) + return c_uuid.value + +@convertStrBytes +def nvmlDeviceGetInforomVersion(handle, infoRomObject): + c_version = create_string_buffer(NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetInforomVersion") + ret = fn(handle, _nvmlInforomObject_t(infoRomObject), + c_version, c_uint(NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE)) + _nvmlCheckReturn(ret) + return c_version.value + +# Added in 4.304 +@convertStrBytes +def nvmlDeviceGetInforomImageVersion(handle): + c_version = create_string_buffer(NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetInforomImageVersion") + ret = fn(handle, c_version, c_uint(NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE)) + _nvmlCheckReturn(ret) + return c_version.value + +# Added in 4.304 +def nvmlDeviceGetInforomConfigurationChecksum(handle): + c_checksum = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetInforomConfigurationChecksum") + ret = fn(handle, byref(c_checksum)) + _nvmlCheckReturn(ret) + return c_checksum.value + +# Added in 4.304 +def nvmlDeviceValidateInforom(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceValidateInforom") + ret = fn(handle) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceGetDisplayMode(handle): + c_mode = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetDisplayMode") + ret = fn(handle, byref(c_mode)) + _nvmlCheckReturn(ret) + return c_mode.value + +def nvmlDeviceGetDisplayActive(handle): + c_mode = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetDisplayActive") + ret = fn(handle, byref(c_mode)) + _nvmlCheckReturn(ret) + return c_mode.value + + +def nvmlDeviceGetPersistenceMode(handle): + c_state = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPersistenceMode") + ret = fn(handle, byref(c_state)) + _nvmlCheckReturn(ret) + return c_state.value + +def nvmlDeviceGetPciInfo_v3(handle): + c_info = nvmlPciInfo_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPciInfo_v3") + ret = fn(handle, byref(c_info)) + _nvmlCheckReturn(ret) + return c_info + +def nvmlDeviceGetPciInfo(handle): + return nvmlDeviceGetPciInfo_v3(handle) + +def nvmlDeviceGetClockInfo(handle, type): + c_clock = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetClockInfo") + ret = fn(handle, _nvmlClockType_t(type), byref(c_clock)) + _nvmlCheckReturn(ret) + return c_clock.value + +# Added in 2.285 +def nvmlDeviceGetMaxClockInfo(handle, type): + c_clock = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMaxClockInfo") + ret = fn(handle, _nvmlClockType_t(type), byref(c_clock)) + _nvmlCheckReturn(ret) + return c_clock.value + +# Added in 4.304 +def nvmlDeviceGetApplicationsClock(handle, type): + c_clock = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetApplicationsClock") + ret = fn(handle, _nvmlClockType_t(type), byref(c_clock)) + _nvmlCheckReturn(ret) + return c_clock.value + +def nvmlDeviceGetMaxCustomerBoostClock(handle, type): + c_clock = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMaxCustomerBoostClock") + ret = fn(handle, _nvmlClockType_t(type), byref(c_clock)) + _nvmlCheckReturn(ret) + return c_clock.value + +def nvmlDeviceGetClock(handle, type, id): + c_clock = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetClock") + ret = fn(handle, _nvmlClockType_t(type), _nvmlClockId_t(id), byref(c_clock)) + _nvmlCheckReturn(ret) + return c_clock.value + +# Added in 5.319 +def nvmlDeviceGetDefaultApplicationsClock(handle, type): + c_clock = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetDefaultApplicationsClock") + ret = fn(handle, _nvmlClockType_t(type), byref(c_clock)) + _nvmlCheckReturn(ret) + return c_clock.value + +# Added in 4.304 +def nvmlDeviceGetSupportedMemoryClocks(handle): + # first call to get the size + c_count = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetSupportedMemoryClocks") + ret = fn(handle, byref(c_count), None) + + if (ret == NVML_SUCCESS): + # special case, no clocks + return [] + elif (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + clocks_array = c_uint * c_count.value + c_clocks = clocks_array() + + # make the call again + ret = fn(handle, byref(c_count), c_clocks) + _nvmlCheckReturn(ret) + + procs = [] + for i in range(c_count.value): + procs.append(c_clocks[i]) + + return procs + else: + # error case + raise NVMLError(ret) + +# Added in 4.304 +def nvmlDeviceGetSupportedGraphicsClocks(handle, memoryClockMHz): + # first call to get the size + c_count = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetSupportedGraphicsClocks") + ret = fn(handle, c_uint(memoryClockMHz), byref(c_count), None) + + if (ret == NVML_SUCCESS): + # special case, no clocks + return [] + elif (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + clocks_array = c_uint * c_count.value + c_clocks = clocks_array() + + # make the call again + ret = fn(handle, c_uint(memoryClockMHz), byref(c_count), c_clocks) + _nvmlCheckReturn(ret) + + procs = [] + for i in range(c_count.value): + procs.append(c_clocks[i]) + + return procs + else: + # error case + raise NVMLError(ret) + +def nvmlDeviceGetFanSpeed(handle): + c_speed = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetFanSpeed") + ret = fn(handle, byref(c_speed)) + _nvmlCheckReturn(ret) + return c_speed.value + +def nvmlDeviceGetFanSpeed_v2(handle, fan): + c_speed = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetFanSpeed_v2") + ret = fn(handle, fan, byref(c_speed)) + _nvmlCheckReturn(ret) + return c_speed.value + +def nvmlDeviceGetTargetFanSpeed(handle, fan): + c_speed = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetTargetFanSpeed") + ret = fn(handle, fan, byref(c_speed)) + _nvmlCheckReturn(ret) + return c_speed.value + +def nvmlDeviceGetNumFans(device): + c_numFans = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetNumFans") + ret = fn(device, byref(c_numFans)) + _nvmlCheckReturn(ret) + return c_numFans.value + +def nvmlDeviceSetDefaultFanSpeed_v2(handle, index): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetDefaultFanSpeed_v2"); + ret = fn(handle, index) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetMinMaxFanSpeed(handle, minSpeed, maxSpeed): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMinMaxFanSpeed") + ret = fn(handle, minSpeed, maxSpeed) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetFanControlPolicy_v2(handle, fan, fanControlPolicy): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetFanControlPolicy_v2") + ret = fn(handle, fan, fanControlPolicy) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceSetFanControlPolicy(handle, fan, fanControlPolicy): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetFanControlPolicy") + ret = fn(handle, fan, _nvmlFanControlPolicy_t(fanControlPolicy)) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetTemperature(handle, sensor): + c_temp = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetTemperature") + ret = fn(handle, _nvmlTemperatureSensors_t(sensor), byref(c_temp)) + _nvmlCheckReturn(ret) + return c_temp.value + +def nvmlDeviceGetTemperatureThreshold(handle, threshold): + c_temp = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetTemperatureThreshold") + ret = fn(handle, _nvmlTemperatureThresholds_t(threshold), byref(c_temp)) + _nvmlCheckReturn(ret) + return c_temp.value + +def nvmlDeviceSetTemperatureThreshold(handle, threshold, temp): + c_temp = c_uint() + c_temp.value = temp + fn = _nvmlGetFunctionPointer("nvmlDeviceSetTemperatureThreshold") + ret = fn(handle, _nvmlTemperatureThresholds_t(threshold), byref(c_temp)) + _nvmlCheckReturn(ret) + return None + +# DEPRECATED use nvmlDeviceGetPerformanceState +def nvmlDeviceGetPowerState(handle): + c_pstate = _nvmlPstates_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerState") + ret = fn(handle, byref(c_pstate)) + _nvmlCheckReturn(ret) + return c_pstate.value + +def nvmlDeviceGetPerformanceState(handle): + c_pstate = _nvmlPstates_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPerformanceState") + ret = fn(handle, byref(c_pstate)) + _nvmlCheckReturn(ret) + return c_pstate.value + +def nvmlDeviceGetPowerManagementMode(handle): + c_pcapMode = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerManagementMode") + ret = fn(handle, byref(c_pcapMode)) + _nvmlCheckReturn(ret) + return c_pcapMode.value + +def nvmlDeviceGetPowerManagementLimit(handle): + c_limit = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerManagementLimit") + ret = fn(handle, byref(c_limit)) + _nvmlCheckReturn(ret) + return c_limit.value + +# Added in 4.304 +def nvmlDeviceGetPowerManagementLimitConstraints(handle): + c_minLimit = c_uint() + c_maxLimit = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerManagementLimitConstraints") + ret = fn(handle, byref(c_minLimit), byref(c_maxLimit)) + _nvmlCheckReturn(ret) + return [c_minLimit.value, c_maxLimit.value] + +# Added in 4.304 +def nvmlDeviceGetPowerManagementDefaultLimit(handle): + c_limit = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerManagementDefaultLimit") + ret = fn(handle, byref(c_limit)) + _nvmlCheckReturn(ret) + return c_limit.value + + +# Added in 331 +def nvmlDeviceGetEnforcedPowerLimit(handle): + c_limit = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetEnforcedPowerLimit") + ret = fn(handle, byref(c_limit)) + _nvmlCheckReturn(ret) + return c_limit.value + +def nvmlDeviceGetPowerUsage(handle): + c_watts = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerUsage") + ret = fn(handle, byref(c_watts)) + _nvmlCheckReturn(ret) + return c_watts.value + +def nvmlDeviceGetTotalEnergyConsumption(handle): + c_millijoules = c_uint64() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetTotalEnergyConsumption") + ret = fn(handle, byref(c_millijoules)) + _nvmlCheckReturn(ret) + return c_millijoules.value + +# Added in 4.304 +def nvmlDeviceGetGpuOperationMode(handle): + c_currState = _nvmlGpuOperationMode_t() + c_pendingState = _nvmlGpuOperationMode_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuOperationMode") + ret = fn(handle, byref(c_currState), byref(c_pendingState)) + _nvmlCheckReturn(ret) + return [c_currState.value, c_pendingState.value] + +# Added in 4.304 +def nvmlDeviceGetCurrentGpuOperationMode(handle): + return nvmlDeviceGetGpuOperationMode(handle)[0] + +# Added in 4.304 +def nvmlDeviceGetPendingGpuOperationMode(handle): + return nvmlDeviceGetGpuOperationMode(handle)[1] + +def nvmlDeviceGetMemoryInfo(handle, version=None): + if not version: + c_memory = c_nvmlMemory_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMemoryInfo") + else: + c_memory = c_nvmlMemory_v2_t() + c_memory.version = version + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMemoryInfo_v2") + ret = fn(handle, byref(c_memory)) + _nvmlCheckReturn(ret) + return c_memory + +def nvmlDeviceGetBAR1MemoryInfo(handle): + c_bar1_memory = c_nvmlBAR1Memory_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetBAR1MemoryInfo") + ret = fn(handle, byref(c_bar1_memory)) + _nvmlCheckReturn(ret) + return c_bar1_memory + +def nvmlDeviceGetComputeMode(handle): + c_mode = _nvmlComputeMode_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetComputeMode") + ret = fn(handle, byref(c_mode)) + _nvmlCheckReturn(ret) + return c_mode.value + +def nvmlDeviceGetCudaComputeCapability(handle): + c_major = c_int() + c_minor = c_int() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetCudaComputeCapability") + ret = fn(handle, byref(c_major), byref(c_minor)) + _nvmlCheckReturn(ret) + return (c_major.value, c_minor.value) + +def nvmlDeviceGetEccMode(handle): + c_currState = _nvmlEnableState_t() + c_pendingState = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetEccMode") + ret = fn(handle, byref(c_currState), byref(c_pendingState)) + _nvmlCheckReturn(ret) + return [c_currState.value, c_pendingState.value] + +# added to API +def nvmlDeviceGetCurrentEccMode(handle): + return nvmlDeviceGetEccMode(handle)[0] + +# added to API +def nvmlDeviceGetPendingEccMode(handle): + return nvmlDeviceGetEccMode(handle)[1] + +def nvmlDeviceGetDefaultEccMode(handle): + c_defaultState = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetDefaultEccMode") + ret = fn(handle, byref(c_defaultState)) + _nvmlCheckReturn(ret) + return [c_defaultState.value] + +def nvmlDeviceGetTotalEccErrors(handle, errorType, counterType): + c_count = c_ulonglong() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetTotalEccErrors") + ret = fn(handle, _nvmlMemoryErrorType_t(errorType), + _nvmlEccCounterType_t(counterType), byref(c_count)) + _nvmlCheckReturn(ret) + return c_count.value + +# This is deprecated, instead use nvmlDeviceGetMemoryErrorCounter +def nvmlDeviceGetDetailedEccErrors(handle, errorType, counterType): + c_counts = c_nvmlEccErrorCounts_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetDetailedEccErrors") + ret = fn(handle, _nvmlMemoryErrorType_t(errorType), + _nvmlEccCounterType_t(counterType), byref(c_counts)) + _nvmlCheckReturn(ret) + return c_counts + +# Added in 4.304 +def nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, locationType): + c_count = c_ulonglong() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMemoryErrorCounter") + ret = fn(handle, + _nvmlMemoryErrorType_t(errorType), + _nvmlEccCounterType_t(counterType), + _nvmlMemoryLocation_t(locationType), + byref(c_count)) + _nvmlCheckReturn(ret) + return c_count.value + +def nvmlDeviceGetUtilizationRates(handle): + c_util = c_nvmlUtilization_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetUtilizationRates") + ret = fn(handle, byref(c_util)) + _nvmlCheckReturn(ret) + return c_util + +def nvmlDeviceGetEncoderUtilization(handle): + c_util = c_uint() + c_samplingPeriod = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetEncoderUtilization") + ret = fn(handle, byref(c_util), byref(c_samplingPeriod)) + _nvmlCheckReturn(ret) + return [c_util.value, c_samplingPeriod.value] + +def nvmlDeviceGetDecoderUtilization(handle): + c_util = c_uint() + c_samplingPeriod = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetDecoderUtilization") + ret = fn(handle, byref(c_util), byref(c_samplingPeriod)) + _nvmlCheckReturn(ret) + return [c_util.value, c_samplingPeriod.value] + +def nvmlDeviceGetPcieReplayCounter(handle): + c_replay = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPcieReplayCounter") + ret = fn(handle, byref(c_replay)) + _nvmlCheckReturn(ret) + return c_replay.value + +def nvmlDeviceGetDriverModel(handle): + c_currModel = _nvmlDriverModel_t() + c_pendingModel = _nvmlDriverModel_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetDriverModel") + ret = fn(handle, byref(c_currModel), byref(c_pendingModel)) + _nvmlCheckReturn(ret) + return [c_currModel.value, c_pendingModel.value] + +# added to API +def nvmlDeviceGetCurrentDriverModel(handle): + return nvmlDeviceGetDriverModel(handle)[0] + +# added to API +def nvmlDeviceGetPendingDriverModel(handle): + return nvmlDeviceGetDriverModel(handle)[1] + +# Added in 2.285 +@convertStrBytes +def nvmlDeviceGetVbiosVersion(handle): + c_version = create_string_buffer(NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetVbiosVersion") + ret = fn(handle, c_version, c_uint(NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE)) + _nvmlCheckReturn(ret) + return c_version.value + +# Added in 2.285 +def nvmlDeviceGetComputeRunningProcesses_v3(handle): + # first call to get the size + c_count = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetComputeRunningProcesses_v3") + ret = fn(handle, byref(c_count), None) + + if (ret == NVML_SUCCESS): + # special case, no running processes + return [] + elif (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + # oversize the array incase more processes are created + c_count.value = c_count.value * 2 + 5 + proc_array = c_nvmlProcessInfo_t * c_count.value + c_procs = proc_array() + + # make the call again + ret = fn(handle, byref(c_count), c_procs) + _nvmlCheckReturn(ret) + + procs = [] + for i in range(c_count.value): + # use an alternative struct for this object + obj = nvmlStructToFriendlyObject(c_procs[i]) + if (obj.usedGpuMemory == NVML_VALUE_NOT_AVAILABLE_ulonglong.value): + # special case for WDDM on Windows, see comment above + obj.usedGpuMemory = None + procs.append(obj) + + return procs + else: + # error case + raise NVMLError(ret) + +def nvmlDeviceGetComputeRunningProcesses(handle): + return nvmlDeviceGetComputeRunningProcesses_v3(handle); + +def nvmlDeviceGetGraphicsRunningProcesses_v3(handle): + # first call to get the size + c_count = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGraphicsRunningProcesses_v3") + ret = fn(handle, byref(c_count), None) + + if (ret == NVML_SUCCESS): + # special case, no running processes + return [] + elif (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + # oversize the array incase more processes are created + c_count.value = c_count.value * 2 + 5 + proc_array = c_nvmlProcessInfo_t * c_count.value + c_procs = proc_array() + + # make the call again + ret = fn(handle, byref(c_count), c_procs) + _nvmlCheckReturn(ret) + + procs = [] + for i in range(c_count.value): + # use an alternative struct for this object + obj = nvmlStructToFriendlyObject(c_procs[i]) + if (obj.usedGpuMemory == NVML_VALUE_NOT_AVAILABLE_ulonglong.value): + # special case for WDDM on Windows, see comment above + obj.usedGpuMemory = None + procs.append(obj) + + return procs + else: + # error case + raise NVMLError(ret) + +def nvmlDeviceGetGraphicsRunningProcesses(handle): + return nvmlDeviceGetGraphicsRunningProcesses_v3(handle) + +def nvmlDeviceGetMPSComputeRunningProcesses(handle): + return nvmlDeviceGetMPSComputeRunningProcesses_v3(handle) + +def nvmlDeviceGetMPSComputeRunningProcesses_v3(handle): + # first call to get the size + c_count = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMPSComputeRunningProcesses_v3") + ret = fn(handle, byref(c_count), None) + + if (ret == NVML_SUCCESS): + # special case, no running processes + return [] + elif (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + # oversize the array incase more processes are created + c_count.value = c_count.value * 2 + 5 + proc_array = c_nvmlProcessInfo_t * c_count.value + c_procs = proc_array() + + # make the call again + ret = fn(handle, byref(c_count), c_procs) + _nvmlCheckReturn(ret) + + procs = [] + for i in range(c_count.value): + # use an alternative struct for this object + obj = nvmlStructToFriendlyObject(c_procs[i]) + if (obj.usedGpuMemory == NVML_VALUE_NOT_AVAILABLE_ulonglong.value): + # special case for WDDM on Windows, see comment above + obj.usedGpuMemory = None + procs.append(obj) + + return procs + else: + # error case + raise NVMLError(ret) + +def nvmlDeviceGetAutoBoostedClocksEnabled(handle): + c_isEnabled = _nvmlEnableState_t() + c_defaultIsEnabled = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetAutoBoostedClocksEnabled") + ret = fn(handle, byref(c_isEnabled), byref(c_defaultIsEnabled)) + _nvmlCheckReturn(ret) + return [c_isEnabled.value, c_defaultIsEnabled.value] + #Throws NVML_ERROR_NOT_SUPPORTED if hardware doesn't support setting auto boosted clocks + +## Set functions +def nvmlUnitSetLedState(unit, color): + fn = _nvmlGetFunctionPointer("nvmlUnitSetLedState") + ret = fn(unit, _nvmlLedColor_t(color)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceSetPersistenceMode(handle, mode): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetPersistenceMode") + ret = fn(handle, _nvmlEnableState_t(mode)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceSetComputeMode(handle, mode): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetComputeMode") + ret = fn(handle, _nvmlComputeMode_t(mode)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceSetEccMode(handle, mode): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetEccMode") + ret = fn(handle, _nvmlEnableState_t(mode)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceClearEccErrorCounts(handle, counterType): + fn = _nvmlGetFunctionPointer("nvmlDeviceClearEccErrorCounts") + ret = fn(handle, _nvmlEccCounterType_t(counterType)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceSetDriverModel(handle, model): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetDriverModel") + ret = fn(handle, _nvmlDriverModel_t(model)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceSetAutoBoostedClocksEnabled(handle, enabled): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetAutoBoostedClocksEnabled") + ret = fn(handle, _nvmlEnableState_t(enabled)) + _nvmlCheckReturn(ret) + return None + #Throws NVML_ERROR_NOT_SUPPORTED if hardware doesn't support setting auto boosted clocks + +def nvmlDeviceSetDefaultAutoBoostedClocksEnabled(handle, enabled, flags): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetDefaultAutoBoostedClocksEnabled") + ret = fn(handle, _nvmlEnableState_t(enabled), c_uint(flags)) + _nvmlCheckReturn(ret) + return None + #Throws NVML_ERROR_NOT_SUPPORTED if hardware doesn't support setting auto boosted clocks + +def nvmlDeviceSetGpuLockedClocks(handle, minGpuClockMHz, maxGpuClockMHz): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetGpuLockedClocks") + ret = fn(handle, c_uint(minGpuClockMHz), c_uint(maxGpuClockMHz)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceResetGpuLockedClocks(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceResetGpuLockedClocks") + ret = fn(handle) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceSetMemoryLockedClocks(handle, minMemClockMHz, maxMemClockMHz): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetMemoryLockedClocks") + ret = fn(handle, c_uint(minMemClockMHz), c_uint(maxMemClockMHz)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceResetMemoryLockedClocks(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceResetMemoryLockedClocks") + ret = fn(handle) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceGetClkMonStatus(handle, c_clkMonInfo): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetClkMonStatus") + ret = fn(handle, c_clkMonInfo) + return ret + +# Added in 4.304 +def nvmlDeviceSetApplicationsClocks(handle, maxMemClockMHz, maxGraphicsClockMHz): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetApplicationsClocks") + ret = fn(handle, c_uint(maxMemClockMHz), c_uint(maxGraphicsClockMHz)) + _nvmlCheckReturn(ret) + return None + +# Added in 4.304 +def nvmlDeviceResetApplicationsClocks(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceResetApplicationsClocks") + ret = fn(handle) + _nvmlCheckReturn(ret) + return None + +# Added in 4.304 +def nvmlDeviceSetPowerManagementLimit(handle, limit): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetPowerManagementLimit") + ret = fn(handle, c_uint(limit)) + _nvmlCheckReturn(ret) + return None + +# Added in 4.304 +def nvmlDeviceSetGpuOperationMode(handle, mode): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetGpuOperationMode") + ret = fn(handle, _nvmlGpuOperationMode_t(mode)) + _nvmlCheckReturn(ret) + return None + +# Added in 2.285 +def nvmlEventSetCreate(): + fn = _nvmlGetFunctionPointer("nvmlEventSetCreate") + eventSet = c_nvmlEventSet_t() + ret = fn(byref(eventSet)) + _nvmlCheckReturn(ret) + return eventSet + +# Added in 2.285 +def nvmlDeviceRegisterEvents(handle, eventTypes, eventSet): + fn = _nvmlGetFunctionPointer("nvmlDeviceRegisterEvents") + ret = fn(handle, c_ulonglong(eventTypes), eventSet) + _nvmlCheckReturn(ret) + return None + +# Added in 2.285 +def nvmlDeviceGetSupportedEventTypes(handle): + c_eventTypes = c_ulonglong() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetSupportedEventTypes") + ret = fn(handle, byref(c_eventTypes)) + _nvmlCheckReturn(ret) + return c_eventTypes.value + +# raises NVML_ERROR_TIMEOUT exception on timeout +def nvmlEventSetWait_v2(eventSet, timeoutms): + fn = _nvmlGetFunctionPointer("nvmlEventSetWait_v2") + data = c_nvmlEventData_t() + ret = fn(eventSet, byref(data), c_uint(timeoutms)) + _nvmlCheckReturn(ret) + return data + +def nvmlEventSetWait(eventSet, timeoutms): + return nvmlEventSetWait_v2(eventSet, timeoutms) + +# Added in 2.285 +def nvmlEventSetFree(eventSet): + fn = _nvmlGetFunctionPointer("nvmlEventSetFree") + ret = fn(eventSet) + _nvmlCheckReturn(ret) + return None + +# Added in 3.295 +def nvmlDeviceOnSameBoard(handle1, handle2): + fn = _nvmlGetFunctionPointer("nvmlDeviceOnSameBoard") + onSameBoard = c_int() + ret = fn(handle1, handle2, byref(onSameBoard)) + _nvmlCheckReturn(ret) + return (onSameBoard.value != 0) + +# Added in 3.295 +def nvmlDeviceGetCurrPcieLinkGeneration(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetCurrPcieLinkGeneration") + gen = c_uint() + ret = fn(handle, byref(gen)) + _nvmlCheckReturn(ret) + return gen.value + +# Added in 3.295 +def nvmlDeviceGetMaxPcieLinkGeneration(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMaxPcieLinkGeneration") + gen = c_uint() + ret = fn(handle, byref(gen)) + _nvmlCheckReturn(ret) + return gen.value + +# Added in 3.295 +def nvmlDeviceGetCurrPcieLinkWidth(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetCurrPcieLinkWidth") + width = c_uint() + ret = fn(handle, byref(width)) + _nvmlCheckReturn(ret) + return width.value + +# Added in 3.295 +def nvmlDeviceGetMaxPcieLinkWidth(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMaxPcieLinkWidth") + width = c_uint() + ret = fn(handle, byref(width)) + _nvmlCheckReturn(ret) + return width.value + +def nvmlDeviceGetGpuMaxPcieLinkGeneration(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuMaxPcieLinkGeneration") + gen = c_uint() + ret = fn(handle, byref(gen)) + _nvmlCheckReturn(ret) + return gen.value + +# Added in 4.304 +def nvmlDeviceGetSupportedClocksThrottleReasons(handle): + c_reasons= c_ulonglong() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetSupportedClocksThrottleReasons") + ret = fn(handle, byref(c_reasons)) + _nvmlCheckReturn(ret) + return c_reasons.value + +# Added in 4.304 +def nvmlDeviceGetCurrentClocksThrottleReasons(handle): + c_reasons= c_ulonglong() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetCurrentClocksThrottleReasons") + ret = fn(handle, byref(c_reasons)) + _nvmlCheckReturn(ret) + return c_reasons.value + +# Added in 5.319 +def nvmlDeviceGetIndex(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetIndex") + c_index = c_uint() + ret = fn(handle, byref(c_index)) + _nvmlCheckReturn(ret) + return c_index.value + +# Added in 5.319 +def nvmlDeviceGetAccountingMode(handle): + c_mode = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetAccountingMode") + ret = fn(handle, byref(c_mode)) + _nvmlCheckReturn(ret) + return c_mode.value + +def nvmlDeviceSetAccountingMode(handle, mode): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetAccountingMode") + ret = fn(handle, _nvmlEnableState_t(mode)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceClearAccountingPids(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceClearAccountingPids") + ret = fn(handle) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceGetAccountingStats(handle, pid): + stats = c_nvmlAccountingStats_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetAccountingStats") + ret = fn(handle, c_uint(pid), byref(stats)) + _nvmlCheckReturn(ret) + if (stats.maxMemoryUsage == NVML_VALUE_NOT_AVAILABLE_ulonglong.value): + # special case for WDDM on Windows, see comment above + stats.maxMemoryUsage = None + return stats + +def nvmlDeviceGetAccountingPids(handle): + count = c_uint(nvmlDeviceGetAccountingBufferSize(handle)) + pids = (c_uint * count.value)() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetAccountingPids") + ret = fn(handle, byref(count), pids) + _nvmlCheckReturn(ret) + return list(map(int, pids[0:count.value])) + +def nvmlDeviceGetAccountingBufferSize(handle): + bufferSize = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetAccountingBufferSize") + ret = fn(handle, byref(bufferSize)) + _nvmlCheckReturn(ret) + return int(bufferSize.value) + +def nvmlDeviceGetRetiredPages(device, sourceFilter): + c_source = _nvmlPageRetirementCause_t(sourceFilter) + c_count = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetRetiredPages") + + # First call will get the size + ret = fn(device, c_source, byref(c_count), None) + + # this should only fail with insufficient size + if ((ret != NVML_SUCCESS) and + (ret != NVML_ERROR_INSUFFICIENT_SIZE)): + raise NVMLError(ret) + + # call again with a buffer + # oversize the array for the rare cases where additional pages + # are retired between NVML calls + c_count.value = c_count.value * 2 + 5 + page_array = c_ulonglong * c_count.value + c_pages = page_array() + ret = fn(device, c_source, byref(c_count), c_pages) + _nvmlCheckReturn(ret) + return list(map(int, c_pages[0:c_count.value])) + +def nvmlDeviceGetRetiredPages_v2(device, sourceFilter): + c_source = _nvmlPageRetirementCause_t(sourceFilter) + c_count = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetRetiredPages_v2") + + # First call will get the size + ret = fn(device, c_source, byref(c_count), None) + + # this should only fail with insufficient size + if ((ret != NVML_SUCCESS) and + (ret != NVML_ERROR_INSUFFICIENT_SIZE)): + raise NVMLError(ret) + + # call again with a buffer + # oversize the array for the rare cases where additional pages + # are retired between NVML calls + c_count.value = c_count.value * 2 + 5 + page_array = c_ulonglong * c_count.value + c_pages = page_array() + times_array = c_ulonglong * c_count.value + c_times = times_array() + ret = fn(device, c_source, byref(c_count), c_pages, c_times) + _nvmlCheckReturn(ret) + return [ { 'address': int(c_pages[i]), 'timestamp': int(c_times[i]) } for i in range(c_count.value) ]; + +def nvmlDeviceGetRetiredPagesPendingStatus(device): + c_pending = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetRetiredPagesPendingStatus") + ret = fn(device, byref(c_pending)) + _nvmlCheckReturn(ret) + return int(c_pending.value) + +def nvmlDeviceGetAPIRestriction(device, apiType): + c_permission = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetAPIRestriction") + ret = fn(device, _nvmlRestrictedAPI_t(apiType), byref(c_permission)) + _nvmlCheckReturn(ret) + return int(c_permission.value) + +def nvmlDeviceSetAPIRestriction(handle, apiType, isRestricted): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetAPIRestriction") + ret = fn(handle, _nvmlRestrictedAPI_t(apiType), _nvmlEnableState_t(isRestricted)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceGetBridgeChipInfo(handle): + bridgeHierarchy = c_nvmlBridgeChipHierarchy_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetBridgeChipInfo") + ret = fn(handle, byref(bridgeHierarchy)) + _nvmlCheckReturn(ret) + return bridgeHierarchy + +def nvmlDeviceGetSamples(device, sampling_type, timeStamp): + c_sampling_type = _nvmlSamplingType_t(sampling_type) + c_time_stamp = c_ulonglong(timeStamp) + c_sample_count = c_uint(0) + c_sample_value_type = _nvmlValueType_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetSamples") + + ## First Call gets the size + ret = fn(device, c_sampling_type, c_time_stamp, byref(c_sample_value_type), byref(c_sample_count), None) + + # Stop if this fails + if (ret != NVML_SUCCESS): + raise NVMLError(ret) + + sampleArray = c_sample_count.value * c_nvmlSample_t + c_samples = sampleArray() + ret = fn(device, c_sampling_type, c_time_stamp, byref(c_sample_value_type), byref(c_sample_count), c_samples) + _nvmlCheckReturn(ret) + return (c_sample_value_type.value, c_samples[0:c_sample_count.value]) + +def nvmlDeviceGetViolationStatus(device, perfPolicyType): + c_perfPolicy_type = _nvmlPerfPolicyType_t(perfPolicyType) + c_violTime = c_nvmlViolationTime_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetViolationStatus") + + ## Invoke the method to get violation time + ret = fn(device, c_perfPolicy_type, byref(c_violTime)) + _nvmlCheckReturn(ret) + return c_violTime + +def nvmlDeviceGetPcieThroughput(device, counter): + c_util = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPcieThroughput") + ret = fn(device, _nvmlPcieUtilCounter_t(counter), byref(c_util)) + _nvmlCheckReturn(ret) + return c_util.value + +def nvmlSystemGetTopologyGpuSet(cpuNumber): + c_count = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlSystemGetTopologyGpuSet") + + # First call will get the size + ret = fn(cpuNumber, byref(c_count), None) + + if ret != NVML_SUCCESS: + raise NVMLError(ret) + # call again with a buffer + device_array = c_nvmlDevice_t * c_count.value + c_devices = device_array() + ret = fn(cpuNumber, byref(c_count), c_devices) + _nvmlCheckReturn(ret) + return list(c_devices[0:c_count.value]) + +def nvmlDeviceGetTopologyNearestGpus(device, level): + c_count = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetTopologyNearestGpus") + + # First call will get the size + ret = fn(device, level, byref(c_count), None) + + if ret != NVML_SUCCESS: + raise NVMLError(ret) + + # call again with a buffer + device_array = c_nvmlDevice_t * c_count.value + c_devices = device_array() + ret = fn(device, level, byref(c_count), c_devices) + _nvmlCheckReturn(ret) + return list(c_devices[0:c_count.value]) + +def nvmlDeviceGetTopologyCommonAncestor(device1, device2): + c_level = _nvmlGpuTopologyLevel_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetTopologyCommonAncestor") + ret = fn(device1, device2, byref(c_level)) + _nvmlCheckReturn(ret) + return c_level.value + +def nvmlDeviceGetNvLinkUtilizationCounter(device, link, counter): + c_rxcounter = c_ulonglong() + c_txcounter = c_ulonglong() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkUtilizationCounter") + ret = fn(device, link, counter, byref(c_rxcounter), byref(c_txcounter)) + _nvmlCheckReturn(ret) + return (c_rxcounter.value, c_txcounter.value) + +def nvmlDeviceFreezeNvLinkUtilizationCounter(device, link, counter, freeze): + fn = _nvmlGetFunctionPointer("nvmlDeviceFreezeNvLinkUtilizationCounter") + ret = fn(device, link, counter, freeze) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceResetNvLinkUtilizationCounter(device, link, counter): + fn = _nvmlGetFunctionPointer("nvmlDeviceResetNvLinkUtilizationCounter") + ret = fn(device, link, counter) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceSetNvLinkUtilizationControl(device, link, counter, control, reset): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetNvLinkUtilizationControl") + ret = fn(device, link, counter, byref(control), reset) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceGetNvLinkUtilizationControl(device, link, counter): + c_control = nvmlNvLinkUtilizationControl_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkUtilizationControl") + ret = fn(device, link, counter, byref(c_control)) + _nvmlCheckReturn(ret) + return c_control + +def nvmlDeviceGetNvLinkCapability(device, link, capability): + c_capResult = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkCapability") + ret = fn(device, link, capability, byref(c_capResult)) + _nvmlCheckReturn(ret) + return c_capResult.value + +def nvmlDeviceGetNvLinkErrorCounter(device, link, counter): + c_result = c_ulonglong() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkErrorCounter") + ret = fn(device, link, counter, byref(c_result)) + _nvmlCheckReturn(ret) + return c_result.value + +def nvmlDeviceResetNvLinkErrorCounters(device, link): + fn = _nvmlGetFunctionPointer("nvmlDeviceResetNvLinkErrorCounters") + ret = fn(device, link) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceGetNvLinkRemotePciInfo(device, link): + c_pci = nvmlPciInfo_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkRemotePciInfo_v2") + ret = fn(device, link, byref(c_pci)) + _nvmlCheckReturn(ret) + return c_pci + +def nvmlDeviceGetNvLinkRemoteDeviceType(handle, link): + c_type = _nvmlNvLinkDeviceType_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkRemoteDeviceType") + ret = fn(handle, link, byref(c_type)) + _nvmlCheckReturn(ret) + return c_type.value + +def nvmlDeviceGetNvLinkState(device, link): + c_isActive = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkState") + ret = fn(device, link, byref(c_isActive)) + _nvmlCheckReturn(ret) + return c_isActive.value + +def nvmlDeviceGetNvLinkVersion(device, link): + c_version = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkVersion") + ret = fn(device, link, byref(c_version)) + _nvmlCheckReturn(ret) + return c_version.value + +def nvmlDeviceModifyDrainState(pciInfo, newState): + fn = _nvmlGetFunctionPointer("nvmlDeviceModifyDrainState") + ret = fn(pointer(pciInfo), newState) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceQueryDrainState(pciInfo): + c_newState = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceQueryDrainState") + ret = fn(pointer(pciInfo), byref(c_newState)) + _nvmlCheckReturn(ret) + return c_newState.value + +def nvmlDeviceRemoveGpu(pciInfo): + fn = _nvmlGetFunctionPointer("nvmlDeviceRemoveGpu") + ret = fn(pointer(pciInfo)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceDiscoverGpus(pciInfo): + fn = _nvmlGetFunctionPointer("nvmlDeviceDiscoverGpus") + ret = fn(pointer(pciInfo)) + _nvmlCheckReturn(ret) + return None + +def nvmlDeviceGetFieldValues(handle, fieldIds): + values_arr = c_nvmlFieldValue_t * len(fieldIds) + values = values_arr() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetFieldValues") + + for i, fieldId in enumerate(fieldIds): + try: + (values[i].fieldId, values[i].scopeId) = fieldId + except TypeError: + values[i].fieldId = fieldId + + ret = fn(handle, c_int32(len(fieldIds)), byref(values)) + _nvmlCheckReturn(ret) + return values + +def nvmlDeviceClearFieldValues(handle, fieldIds): + values_arr = c_nvmlFieldValue_t * len(fieldIds) + values = values_arr() + fn = _nvmlGetFunctionPointer("nvmlDeviceClearFieldValues") + + for i, fieldId in enumerate(fieldIds): + try: + (values[i].fieldId, values[i].scopeId) = fieldId + except TypeError: + values[i].fieldId = fieldId + + ret = fn(handle, c_int32(len(fieldIds)), byref(values)) + _nvmlCheckReturn(ret) + return values + +def nvmlDeviceGetVirtualizationMode(handle): + c_virtualization_mode = c_ulonglong() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetVirtualizationMode") + ret = fn(handle, byref(c_virtualization_mode)) + _nvmlCheckReturn(ret) + return c_virtualization_mode.value + +def nvmlDeviceSetVirtualizationMode(handle, virtualization_mode): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetVirtualizationMode") + return fn(handle, virtualization_mode) + +def nvmlGetVgpuDriverCapabilities(capability): + c_capResult = c_uint() + fn = _nvmlGetFunctionPointer("nvmlGetVgpuDriverCapabilities") + ret = fn(_nvmlVgpuDriverCapability_t(capability), byref(c_capResult)) + _nvmlCheckReturn(ret) + return c_capResult.value + +def nvmlDeviceGetVgpuCapabilities(handle, capability): + c_capResult = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetVgpuCapabilities") + ret = fn(handle, _nvmlDeviceVgpuCapability_t(capability), byref(c_capResult)) + _nvmlCheckReturn(ret) + return c_capResult.value + +def nvmlDeviceGetSupportedVgpus(handle): + # first call to get the size + c_vgpu_count = c_uint(0) + + fn = _nvmlGetFunctionPointer("nvmlDeviceGetSupportedVgpus") + ret = fn(handle, byref(c_vgpu_count), None) + + if (ret == NVML_SUCCESS): + # special case, no supported vGPUs + return [] + elif (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + vgpu_type_ids_array = _nvmlVgpuTypeId_t * c_vgpu_count.value + c_vgpu_type_ids = vgpu_type_ids_array() + + # make the call again + ret = fn(handle, byref(c_vgpu_count), c_vgpu_type_ids) + _nvmlCheckReturn(ret) + vgpus = [] + for i in range(c_vgpu_count.value): + vgpus.append(c_vgpu_type_ids[i]) + return vgpus + else: + # error case + raise NVMLError(ret) + +def nvmlDeviceGetCreatableVgpus(handle): + # first call to get the size + c_vgpu_count = c_uint(0) + + fn = _nvmlGetFunctionPointer("nvmlDeviceGetCreatableVgpus") + ret = fn(handle, byref(c_vgpu_count), None) + + if (ret == NVML_SUCCESS): + # special case, no supported vGPUs + return [] + elif (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + vgpu_type_ids_array = _nvmlVgpuTypeId_t * c_vgpu_count.value + c_vgpu_type_ids = vgpu_type_ids_array() + + # make the call again + ret = fn(handle, byref(c_vgpu_count), c_vgpu_type_ids) + _nvmlCheckReturn(ret) + vgpus = [] + for i in range(c_vgpu_count.value): + vgpus.append(c_vgpu_type_ids[i]) + return vgpus + else: + # error case + raise NVMLError(ret) + +def nvmlVgpuTypeGetGpuInstanceProfileId(vgpuTypeId): + c_profile_id = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetGpuInstanceProfileId") + ret = fn(vgpuTypeId, byref(c_profile_id)) + _nvmlCheckReturn(ret) + return (c_profile_id.value) + +@convertStrBytes +def nvmlVgpuTypeGetClass(vgpuTypeId): + c_class = create_string_buffer(NVML_DEVICE_NAME_BUFFER_SIZE) + c_buffer_size = c_uint(NVML_DEVICE_NAME_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetClass") + ret = fn(vgpuTypeId, c_class, byref(c_buffer_size)) + _nvmlCheckReturn(ret) + return c_class.value + +@convertStrBytes +def nvmlVgpuTypeGetName(vgpuTypeId): + c_name = create_string_buffer(NVML_DEVICE_NAME_BUFFER_SIZE) + c_buffer_size = c_uint(NVML_DEVICE_NAME_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetName") + ret = fn(vgpuTypeId, c_name, byref(c_buffer_size)) + _nvmlCheckReturn(ret) + return c_name.value + +def nvmlVgpuTypeGetDeviceID(vgpuTypeId): + c_device_id = c_ulonglong(0) + c_subsystem_id = c_ulonglong(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetDeviceID") + ret = fn(vgpuTypeId, byref(c_device_id), byref(c_subsystem_id)) + _nvmlCheckReturn(ret) + return (c_device_id.value, c_subsystem_id.value) + +def nvmlVgpuTypeGetFramebufferSize(vgpuTypeId): + c_fb_size = c_ulonglong(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetFramebufferSize") + ret = fn(vgpuTypeId, byref(c_fb_size)) + _nvmlCheckReturn(ret) + return c_fb_size.value + +def nvmlVgpuTypeGetNumDisplayHeads(vgpuTypeId): + c_num_heads = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetNumDisplayHeads") + ret = fn(vgpuTypeId, byref(c_num_heads)) + _nvmlCheckReturn(ret) + return c_num_heads.value + +def nvmlVgpuTypeGetResolution(vgpuTypeId): + c_xdim = c_uint(0) + c_ydim = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetResolution") + ret = fn(vgpuTypeId, 0, byref(c_xdim), byref(c_ydim)) + _nvmlCheckReturn(ret) + return (c_xdim.value, c_ydim.value) + +@convertStrBytes +def nvmlVgpuTypeGetLicense(vgpuTypeId): + c_license = create_string_buffer(NVML_GRID_LICENSE_BUFFER_SIZE) + c_buffer_size = c_uint(NVML_GRID_LICENSE_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetLicense") + ret = fn(vgpuTypeId, c_license, c_buffer_size) + _nvmlCheckReturn(ret) + return c_license.value + +def nvmlVgpuTypeGetFrameRateLimit(vgpuTypeId): + c_frl_config = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetFrameRateLimit") + ret = fn(vgpuTypeId, byref(c_frl_config)) + _nvmlCheckReturn(ret) + return c_frl_config.value + +def nvmlVgpuTypeGetMaxInstances(handle, vgpuTypeId): + c_max_instances = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetMaxInstances") + ret = fn(handle, vgpuTypeId, byref(c_max_instances)) + _nvmlCheckReturn(ret) + return c_max_instances.value + +def nvmlVgpuTypeGetMaxInstancesPerVm(vgpuTypeId): + c_max_instances_per_vm = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetMaxInstancesPerVm") + ret = fn(vgpuTypeId, byref(c_max_instances_per_vm)) + _nvmlCheckReturn(ret) + return c_max_instances_per_vm.value + +def nvmlDeviceGetActiveVgpus(handle): + # first call to get the size + c_vgpu_count = c_uint(0) + + fn = _nvmlGetFunctionPointer("nvmlDeviceGetActiveVgpus") + ret = fn(handle, byref(c_vgpu_count), None) + + if (ret == NVML_SUCCESS): + # special case, no active vGPUs + return [] + elif (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + vgpu_instance_array = _nvmlVgpuInstance_t * c_vgpu_count.value + c_vgpu_instances = vgpu_instance_array() + + # make the call again + ret = fn(handle, byref(c_vgpu_count), c_vgpu_instances) + _nvmlCheckReturn(ret) + vgpus = [] + for i in range(c_vgpu_count.value): + vgpus.append(c_vgpu_instances[i]) + return vgpus + else: + # error case + raise NVMLError(ret) + +@convertStrBytes +def nvmlVgpuInstanceGetVmID(vgpuInstance): + c_vm_id = create_string_buffer(NVML_DEVICE_UUID_BUFFER_SIZE) + c_buffer_size = c_uint(NVML_GRID_LICENSE_BUFFER_SIZE) + c_vm_id_type = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetVmID") + ret = fn(vgpuInstance, byref(c_vm_id), c_buffer_size, byref(c_vm_id_type)) + _nvmlCheckReturn(ret) + return (c_vm_id.value, c_vm_id_type.value) + +@convertStrBytes +def nvmlVgpuInstanceGetUUID(vgpuInstance): + c_uuid = create_string_buffer(NVML_DEVICE_UUID_BUFFER_SIZE) + c_buffer_size = c_uint(NVML_DEVICE_UUID_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetUUID") + ret = fn(vgpuInstance, byref(c_uuid), c_buffer_size) + _nvmlCheckReturn(ret) + return c_uuid.value + +@convertStrBytes +def nvmlVgpuInstanceGetMdevUUID(vgpuInstance): + c_uuid = create_string_buffer(NVML_DEVICE_UUID_BUFFER_SIZE) + c_buffer_size = c_uint(NVML_DEVICE_UUID_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetMdevUUID") + ret = fn(vgpuInstance, byref(c_uuid), c_buffer_size) + _nvmlCheckReturn(ret) + return c_uuid.value + +@convertStrBytes +def nvmlVgpuInstanceGetVmDriverVersion(vgpuInstance): + c_driver_version = create_string_buffer(NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE) + c_buffer_size = c_uint(NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetVmDriverVersion") + ret = fn(vgpuInstance, byref(c_driver_version), c_buffer_size) + _nvmlCheckReturn(ret) + return c_driver_version.value + +def nvmlVgpuInstanceGetLicenseStatus(vgpuInstance): + c_license_status = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetLicenseStatus") + ret = fn(vgpuInstance, byref(c_license_status)) + _nvmlCheckReturn(ret) + return c_license_status.value + +def nvmlVgpuInstanceGetLicenseInfo_v2(vgpuInstance): + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetLicenseInfo_v2") + c_license_info = c_nvmlVgpuLicenseInfo_t() + ret = fn(vgpuInstance, byref(c_license_info)) + _nvmlCheckReturn(ret) + return c_license_info + +def nvmlVgpuInstanceGetLicenseInfo(vgpuInstance): + return nvmlVgpuInstanceGetLicenseInfo_v2(vgpuInstance) + +def nvmlVgpuInstanceGetFrameRateLimit(vgpuInstance): + c_frl = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetFrameRateLimit") + ret = fn(vgpuInstance, byref(c_frl)) + _nvmlCheckReturn(ret) + return c_frl.value + +def nvmlVgpuInstanceGetEccMode(vgpuInstance): + c_mode = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetEccMode") + ret = fn(vgpuInstance, byref(c_mode)) + _nvmlCheckReturn(ret) + return c_mode.value + +def nvmlVgpuInstanceGetType(vgpuInstance): + c_vgpu_type = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetType") + ret = fn(vgpuInstance, byref(c_vgpu_type)) + _nvmlCheckReturn(ret) + return c_vgpu_type.value + +def nvmlVgpuInstanceGetEncoderCapacity(vgpuInstance): + c_encoder_capacity = c_ulonglong(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetEncoderCapacity") + ret = fn(vgpuInstance, byref(c_encoder_capacity)) + _nvmlCheckReturn(ret) + return c_encoder_capacity.value + +def nvmlVgpuInstanceSetEncoderCapacity(vgpuInstance, encoder_capacity): + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceSetEncoderCapacity") + return fn(vgpuInstance, encoder_capacity) + +def nvmlVgpuInstanceGetFbUsage(vgpuInstance): + c_fb_usage = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetFbUsage") + ret = fn(vgpuInstance, byref(c_fb_usage)) + _nvmlCheckReturn(ret) + return c_fb_usage.value + +def nvmlVgpuTypeGetCapabilities(vgpuTypeId, capability): + c_cap_result = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuTypeGetCapabilities") + ret = fn(vgpuTypeId, _nvmlVgpuCapability_t(capability), byref(c_cap_result)) + _nvmlCheckReturn(ret) + return (c_cap_result.value) + +def nvmlVgpuInstanceGetGpuInstanceId(vgpuInstance): + c_id = c_uint(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetGpuInstanceId") + ret = fn(vgpuInstance, byref(c_id)) + _nvmlCheckReturn(ret) + return (c_id.value) + +@convertStrBytes +def nvmlVgpuInstanceGetGpuPciId(vgpuInstance): + c_vgpuPciId = create_string_buffer(NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetGpuPciId") + ret = fn(vgpuInstance, c_vgpuPciId, byref(c_uint(NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE))) + _nvmlCheckReturn(ret) + return c_vgpuPciId.value + +def nvmlDeviceGetVgpuUtilization(handle, timeStamp): + # first call to get the size + c_vgpu_count = c_uint(0) + c_time_stamp = c_ulonglong(timeStamp) + c_sample_value_type = _nvmlValueType_t() + + fn = _nvmlGetFunctionPointer("nvmlDeviceGetVgpuUtilization") + ret = fn(handle, c_time_stamp, byref(c_sample_value_type), byref(c_vgpu_count), None) + + if (ret == NVML_SUCCESS): + # special case, no active vGPUs + return [] + elif (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + sampleArray = c_vgpu_count.value * c_nvmlVgpuInstanceUtilizationSample_t + c_samples = sampleArray() + + # make the call again + ret = fn(handle, c_time_stamp, byref(c_sample_value_type), byref(c_vgpu_count), c_samples) + _nvmlCheckReturn(ret) + + return c_samples[0:c_vgpu_count.value] + else: + # error case + raise NVMLError(ret) + +def nvmlDeviceGetP2PStatus(device1, device2, p2pIndex): + c_p2pstatus = _nvmlGpuP2PStatus_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetP2PStatus") + ret = fn(device1, device2,p2pIndex, byref(c_p2pstatus)) + _nvmlCheckReturn(ret) + return c_p2pstatus.value + +def nvmlDeviceGetGridLicensableFeatures_v4(handle): + c_get_grid_licensable_features = c_nvmlGridLicensableFeatures_v4_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGridLicensableFeatures_v4") + ret = fn(handle, byref(c_get_grid_licensable_features)) + _nvmlCheckReturn(ret) + + return (c_get_grid_licensable_features) + +def nvmlDeviceGetGridLicensableFeatures(handle): + return nvmlDeviceGetGridLicensableFeatures_v4(handle) + +def nvmlDeviceGetGspFirmwareVersion(handle, version): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGspFirmwareVersion") + ret = fn(handle, version) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetGspFirmwareMode(handle, isEnabled, defaultMode): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGspFirmwareMode") + ret = fn(handle, isEnabled, defaultMode) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetEncoderCapacity(handle, encoderQueryType): + c_encoder_capacity = c_ulonglong(0) + c_encoderQuery_type = _nvmlEncoderQueryType_t(encoderQueryType) + + fn = _nvmlGetFunctionPointer("nvmlDeviceGetEncoderCapacity") + ret = fn(handle, c_encoderQuery_type, byref(c_encoder_capacity)) + _nvmlCheckReturn(ret) + return c_encoder_capacity.value + +def nvmlDeviceGetVgpuProcessUtilization(handle, timeStamp): + # first call to get the size + c_vgpu_count = c_uint(0) + c_time_stamp = c_ulonglong(timeStamp) + + fn = _nvmlGetFunctionPointer("nvmlDeviceGetVgpuProcessUtilization") + ret = fn(handle, c_time_stamp, byref(c_vgpu_count), None) + + if (ret == NVML_SUCCESS): + # special case, no active vGPUs + return [] + elif (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + sampleArray = c_vgpu_count.value * c_nvmlVgpuProcessUtilizationSample_t + c_samples = sampleArray() + + # make the call again + ret = fn(handle, c_time_stamp, byref(c_vgpu_count), c_samples) + _nvmlCheckReturn(ret) + + return c_samples[0:c_vgpu_count.value] + else: + # error case + raise NVMLError(ret) + +def nvmlDeviceGetEncoderStats(handle): + c_encoderCount = c_ulonglong(0) + c_encodeFps = c_ulonglong(0) + c_encoderLatency = c_ulonglong(0) + fn = _nvmlGetFunctionPointer("nvmlDeviceGetEncoderStats") + ret = fn(handle, byref(c_encoderCount), byref(c_encodeFps), byref(c_encoderLatency)) + _nvmlCheckReturn(ret) + return (c_encoderCount.value, c_encodeFps.value, c_encoderLatency.value) + +def nvmlDeviceGetEncoderSessions(handle): + # first call to get the size + c_session_count = c_uint(0) + + fn = _nvmlGetFunctionPointer("nvmlDeviceGetEncoderSessions") + ret = fn(handle, byref(c_session_count), None) + + if (ret == NVML_SUCCESS): + if (c_session_count.value != 0): + # typical case + session_array = c_nvmlEncoderSession_t * c_session_count.value + c_sessions = session_array() + + # make the call again + ret = fn(handle, byref(c_session_count), c_sessions) + _nvmlCheckReturn(ret) + sessions = [] + for i in range(c_session_count.value): + sessions.append(c_sessions[i]) + return sessions + else: + return [] # no active sessions + else: + # error case + raise NVMLError(ret) + +def nvmlDeviceGetFBCStats(handle): + c_fbcStats = c_nvmlFBCStats_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetFBCStats") + ret = fn(handle, byref(c_fbcStats)) + _nvmlCheckReturn(ret) + return c_fbcStats + +def nvmlDeviceGetFBCSessions(handle): + # first call to get the size + c_session_count = c_uint(0) + + fn = _nvmlGetFunctionPointer("nvmlDeviceGetFBCSessions") + ret = fn(handle, byref(c_session_count), None) + + if (ret == NVML_SUCCESS): + if (c_session_count.value != 0): + # typical case + session_array = c_nvmlFBCSession_t * c_session_count.value + c_sessions = session_array() + + # make the call again + ret = fn(handle, byref(c_session_count), c_sessions) + _nvmlCheckReturn(ret) + sessions = [] + for i in range(c_session_count.value): + sessions.append(c_sessions[i]) + return sessions + else: + return [] # no active sessions + else: + # error case + raise NVMLError(ret) + +def nvmlVgpuInstanceGetEncoderStats(vgpuInstance): + c_encoderCount = c_ulonglong(0) + c_encodeFps = c_ulonglong(0) + c_encoderLatency = c_ulonglong(0) + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetEncoderStats") + ret = fn(vgpuInstance, byref(c_encoderCount), byref(c_encodeFps), byref(c_encoderLatency)) + _nvmlCheckReturn(ret) + return (c_encoderCount.value, c_encodeFps.value, c_encoderLatency.value) + +def nvmlVgpuInstanceGetEncoderSessions(vgpuInstance): + # first call to get the size + c_session_count = c_uint(0) + + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetEncoderSessions") + ret = fn(vgpuInstance, byref(c_session_count), None) + + if (ret == NVML_SUCCESS): + if (c_session_count.value != 0): + # typical case + session_array = c_nvmlEncoderSession_t * c_session_count.value + c_sessions = session_array() + + # make the call again + ret = fn(vgpuInstance, byref(c_session_count), c_sessions) + _nvmlCheckReturn(ret) + sessions = [] + for i in range(c_session_count.value): + sessions.append(c_sessions[i]) + return sessions + else: + return [] # no active sessions + else: + # error case + raise NVMLError(ret) + +def nvmlVgpuInstanceGetFBCStats(vgpuInstance): + c_fbcStats = c_nvmlFBCStats_t() + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetFBCStats") + ret = fn(vgpuInstance, byref(c_fbcStats)) + _nvmlCheckReturn(ret) + return c_fbcStats + +def nvmlVgpuInstanceGetFBCSessions(vgpuInstance): + # first call to get the size + c_session_count = c_uint(0) + + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetFBCSessions") + ret = fn(vgpuInstance, byref(c_session_count), None) + + if (ret == NVML_SUCCESS): + if (c_session_count.value != 0): + # typical case + session_array = c_nvmlFBCSession_t * c_session_count.value + c_sessions = session_array() + + # make the call again + ret = fn(vgpuInstance, byref(c_session_count), c_sessions) + _nvmlCheckReturn(ret) + sessions = [] + for i in range(c_session_count.value): + sessions.append(c_sessions[i]) + return sessions + else: + return [] # no active sessions + else: + # error case + raise NVMLError(ret) + +def nvmlDeviceGetProcessUtilization(handle, timeStamp): + # first call to get the size + c_count = c_uint(0) + c_time_stamp = c_ulonglong(timeStamp) + + fn = _nvmlGetFunctionPointer("nvmlDeviceGetProcessUtilization") + ret = fn(handle, None, byref(c_count), c_time_stamp) + + if (ret == NVML_ERROR_INSUFFICIENT_SIZE): + # typical case + sampleArray = c_count.value * c_nvmlProcessUtilizationSample_t + c_samples = sampleArray() + + # make the call again + ret = fn(handle, c_samples, byref(c_count), c_time_stamp) + _nvmlCheckReturn(ret) + + return c_samples[0:c_count.value] + else: + # error case + raise NVMLError(ret) + +def nvmlVgpuInstanceGetMetadata(vgpuInstance): + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetMetadata") + c_vgpuMetadata = c_nvmlVgpuMetadata_t() + c_bufferSize = c_uint(0) + # Make the first NVML API call to get the c_bufferSize value. + # We have already allocated required buffer above. + ret = fn(vgpuInstance, byref(c_vgpuMetadata), byref(c_bufferSize)) + if (ret == NVML_ERROR_INSUFFICIENT_SIZE): + ret = fn(vgpuInstance, byref(c_vgpuMetadata), byref(c_bufferSize)) + _nvmlCheckReturn(ret) + else: + raise NVMLError(ret) + return c_vgpuMetadata + +def nvmlDeviceGetVgpuMetadata(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetVgpuMetadata") + c_vgpuPgpuMetadata = c_nvmlVgpuPgpuMetadata_t() + c_bufferSize = c_uint(0) + # Make the first NVML API call to get the c_bufferSize value. + # We have already allocated required buffer above. + ret = fn(handle, byref(c_vgpuPgpuMetadata), byref(c_bufferSize)) + if (ret == NVML_ERROR_INSUFFICIENT_SIZE): + ret = fn(handle, byref(c_vgpuPgpuMetadata), byref(c_bufferSize)) + _nvmlCheckReturn(ret) + else: + raise NVMLError(ret) + return c_vgpuPgpuMetadata + +def nvmlGetVgpuCompatibility(vgpuMetadata, pgpuMetadata): + fn = _nvmlGetFunctionPointer("nvmlGetVgpuCompatibility") + c_vgpuPgpuCompatibility = c_nvmlVgpuPgpuCompatibility_t() + ret = fn(byref(vgpuMetadata), byref(pgpuMetadata), byref(c_vgpuPgpuCompatibility)) + _nvmlCheckReturn(ret) + return c_vgpuPgpuCompatibility + +@convertStrBytes +def nvmlDeviceGetPgpuMetadataString(handle): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPgpuMetadataString") + c_pgpuMetadata = create_string_buffer(NVML_VGPU_PGPU_METADATA_OPAQUE_DATA_SIZE) + c_bufferSize = c_uint(0) + # Make the first NVML API call to get the c_bufferSize value. + # We have already allocated required buffer above. + ret = fn(handle, byref(c_pgpuMetadata), byref(c_bufferSize)) + if (ret == NVML_ERROR_INSUFFICIENT_SIZE): + ret = fn(handle, byref(c_pgpuMetadata), byref(c_bufferSize)) + _nvmlCheckReturn(ret) + else: + raise NVMLError(ret) + return (c_pgpuMetadata.value, c_bufferSize.value) + +def nvmlDeviceGetVgpuSchedulerLog(handle): + c_vgpu_sched_log = c_nvmlVgpuSchedulerLog_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetVgpuSchedulerLog") + ret = fn(handle, byref(c_vgpu_sched_log)) + _nvmlCheckReturn(ret) + return c_vgpu_sched_log + +def nvmlDeviceGetVgpuSchedulerState(handle): + c_vgpu_sched_state = c_nvmlVgpuSchedulerGetState_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetVgpuSchedulerState") + ret = fn(handle, byref(c_vgpu_sched_state)) + _nvmlCheckReturn(ret) + return c_vgpu_sched_state + +def nvmlDeviceGetVgpuSchedulerCapabilities(handle): + c_vgpu_sched_caps = c_nvmlVgpuSchedulerCapabilities_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetVgpuSchedulerCapabilities") + ret = fn(handle, byref(c_vgpu_sched_caps)) + _nvmlCheckReturn(ret) + return c_vgpu_sched_caps + +def nvmlSetVgpuVersion(vgpuVersion): + fn = _nvmlGetFunctionPointer("nvmlSetVgpuVersion") + ret = fn(byref(vgpuVersion)) + _nvmlCheckReturn(ret) + return ret + +def nvmlGetVgpuVersion(supported, current): + fn = _nvmlGetFunctionPointer("nvmlGetVgpuVersion") + ret = fn(byref(supported), byref(current)) + _nvmlCheckReturn(ret) + return ret + +def nvmlVgpuInstanceGetAccountingMode(vgpuInstance): + c_mode = _nvmlEnableState_t() + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetAccountingMode") + ret = fn(vgpuInstance, byref(c_mode)) + _nvmlCheckReturn(ret) + return c_mode.value + +def nvmlVgpuInstanceGetAccountingPids(vgpuInstance): + c_pidCount = c_uint() + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetAccountingPids") + ret = fn(vgpuInstance, byref(c_pidCount), None) + if (ret == NVML_ERROR_INSUFFICIENT_SIZE): + sampleArray = c_pidCount.value * c_uint + c_pidArray = sampleArray() + ret = fn(vgpuInstance, byref(c_pidCount), byref(c_pidArray)) + _nvmlCheckReturn(ret) + else: + raise NVMLError(ret) + return (c_pidCount, c_pidArray) + +def nvmlVgpuInstanceGetAccountingStats(vgpuInstance, pid): + c_accountingStats = c_nvmlAccountingStats_t() + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetAccountingStats") + ret = fn(vgpuInstance, pid, byref(c_accountingStats)) + _nvmlCheckReturn(ret) + return c_accountingStats + +def nvmlVgpuInstanceClearAccountingPids(vgpuInstance): + fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceClearAccountingPids") + ret = fn(vgpuInstance) + _nvmlCheckReturn(ret) + return ret + +def nvmlGetExcludedDeviceCount(): + c_count = c_uint() + fn = _nvmlGetFunctionPointer("nvmlGetExcludedDeviceCount") + ret = fn(byref(c_count)) + _nvmlCheckReturn(ret) + return c_count.value + +def nvmlGetExcludedDeviceInfoByIndex(index): + c_index = c_uint(index) + info = c_nvmlExcludedDeviceInfo_t() + fn = _nvmlGetFunctionPointer("nvmlGetExcludedDeviceInfoByIndex") + ret = fn(c_index, byref(info)) + _nvmlCheckReturn(ret) + return info + +def nvmlDeviceGetHostVgpuMode(handle): + c_host_vgpu_mode = _nvmlHostVgpuMode_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetHostVgpuMode") + ret = fn(handle, byref(c_host_vgpu_mode)) + _nvmlCheckReturn(ret) + return c_host_vgpu_mode.value + +def nvmlDeviceSetMigMode(device, mode): + c_activationStatus = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceSetMigMode") + ret = fn(device, mode, byref(c_activationStatus)) + _nvmlCheckReturn(ret) + return c_activationStatus.value + +def nvmlDeviceGetMigMode(device): + c_currentMode = c_uint() + c_pendingMode = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMigMode") + ret = fn(device, byref(c_currentMode), byref(c_pendingMode)) + _nvmlCheckReturn(ret) + return [c_currentMode.value, c_pendingMode.value] + +def nvmlDeviceGetGpuInstanceProfileInfo(device, profile, version=2): + if version == 2: + c_info = c_nvmlGpuInstanceProfileInfo_v2_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuInstanceProfileInfoV") + elif version == 1: + c_info = c_nvmlGpuInstanceProfileInfo_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuInstanceProfileInfo") + else: + raise NVMLError(NVML_ERROR_FUNCTION_NOT_FOUND) + ret = fn(device, profile, byref(c_info)) + _nvmlCheckReturn(ret) + return c_info + +# Define function alias for the API exposed by NVML +nvmlDeviceGetGpuInstanceProfileInfoV = nvmlDeviceGetGpuInstanceProfileInfo + +def nvmlDeviceGetGpuInstanceRemainingCapacity(device, profileId): + c_count = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuInstanceRemainingCapacity") + ret = fn(device, profileId, byref(c_count)) + _nvmlCheckReturn(ret) + return c_count.value + +def nvmlDeviceGetGpuInstancePossiblePlacements(device, profileId, placementsRef, countRef): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuInstancePossiblePlacements_v2") + ret = fn(device, profileId, placementsRef, countRef) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceCreateGpuInstance(device, profileId): + c_instance = c_nvmlGpuInstance_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceCreateGpuInstance") + ret = fn(device, profileId, byref(c_instance)) + _nvmlCheckReturn(ret) + return c_instance + +def nvmlDeviceCreateGpuInstanceWithPlacement(device, profileId, placement): + c_instance = c_nvmlGpuInstance_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceCreateGpuInstanceWithPlacement") + ret = fn(device, profileId, placement, byref(c_instance)) + _nvmlCheckReturn(ret) + return c_instance + +def nvmlGpuInstanceDestroy(gpuInstance): + fn = _nvmlGetFunctionPointer("nvmlGpuInstanceDestroy") + ret = fn(gpuInstance) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetGpuInstances(device, profileId, gpuInstancesRef, countRef): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuInstances") + ret = fn(device, profileId, gpuInstancesRef, countRef) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetGpuInstanceById(device, gpuInstanceId): + c_instance = c_nvmlGpuInstance_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuInstanceById") + ret = fn(device, gpuInstanceId, byref(c_instance)) + _nvmlCheckReturn(ret) + return c_instance + +def nvmlGpuInstanceGetInfo(gpuInstance): + c_info = c_nvmlGpuInstanceInfo_t() + fn = _nvmlGetFunctionPointer("nvmlGpuInstanceGetInfo") + ret = fn(gpuInstance, byref(c_info)) + _nvmlCheckReturn(ret) + return c_info + +def nvmlGpuInstanceGetComputeInstanceProfileInfo(device, profile, engProfile, version=2): + if version == 2: + c_info = c_nvmlComputeInstanceProfileInfo_v2_t() + fn = _nvmlGetFunctionPointer("nvmlGpuInstanceGetComputeInstanceProfileInfoV") + elif version == 1: + c_info = c_nvmlComputeInstanceProfileInfo_t() + fn = _nvmlGetFunctionPointer("nvmlGpuInstanceGetComputeInstanceProfileInfo") + else: + raise NVMLError(NVML_ERROR_FUNCTION_NOT_FOUND) + ret = fn(device, profile, engProfile, byref(c_info)) + _nvmlCheckReturn(ret) + return c_info + +# Define function alias for the API exposed by NVML +nvmlGpuInstanceGetComputeInstanceProfileInfoV = nvmlGpuInstanceGetComputeInstanceProfileInfo + +def nvmlGpuInstanceGetComputeInstanceRemainingCapacity(gpuInstance, profileId): + c_count = c_uint() + fn = _nvmlGetFunctionPointer("nvmlGpuInstanceGetComputeInstanceRemainingCapacity") + ret = fn(gpuInstance, profileId, byref(c_count)) + _nvmlCheckReturn(ret) + return c_count.value + +def nvmlGpuInstanceGetComputeInstancePossiblePlacements(gpuInstance, profileId, placementsRef, countRef): + fn = _nvmlGetFunctionPointer("nvmlGpuInstanceGetComputeInstancePossiblePlacements") + ret = fn(gpuInstance, profileId, placementsRef, countRef) + _nvmlCheckReturn(ret) + return ret + +def nvmlGpuInstanceCreateComputeInstance(gpuInstance, profileId): + c_instance = c_nvmlComputeInstance_t() + fn = _nvmlGetFunctionPointer("nvmlGpuInstanceCreateComputeInstance") + ret = fn(gpuInstance, profileId, byref(c_instance)) + _nvmlCheckReturn(ret) + return c_instance + +def nvmlGpuInstanceCreateComputeInstanceWithPlacement(gpuInstance, profileId, placement): + c_instance = c_nvmlComputeInstance_t() + fn = _nvmlGetFunctionPointer("nvmlGpuInstanceCreateComputeInstanceWithPlacement") + ret = fn(gpuInstance, profileId, placement, byref(c_instance)) + _nvmlCheckReturn(ret) + return c_instance + +def nvmlComputeInstanceDestroy(computeInstance): + fn = _nvmlGetFunctionPointer("nvmlComputeInstanceDestroy") + ret = fn(computeInstance) + _nvmlCheckReturn(ret) + return ret + +def nvmlGpuInstanceGetComputeInstances(gpuInstance, profileId, computeInstancesRef, countRef): + fn = _nvmlGetFunctionPointer("nvmlGpuInstanceGetComputeInstances") + ret = fn(gpuInstance, profileId, computeInstancesRef, countRef) + _nvmlCheckReturn(ret) + return ret + +def nvmlGpuInstanceGetComputeInstanceById(gpuInstance, computeInstanceId): + c_instance = c_nvmlComputeInstance_t() + fn = _nvmlGetFunctionPointer("nvmlGpuInstanceGetComputeInstanceById") + ret = fn(gpuInstance, computeInstanceId, byref(c_instance)) + _nvmlCheckReturn(ret) + return c_instance + +def nvmlComputeInstanceGetInfo_v2(computeInstance): + c_info = c_nvmlComputeInstanceInfo_t() + fn = _nvmlGetFunctionPointer("nvmlComputeInstanceGetInfo_v2") + ret = fn(computeInstance, byref(c_info)) + _nvmlCheckReturn(ret) + return c_info + +def nvmlComputeInstanceGetInfo(computeInstance): + return nvmlComputeInstanceGetInfo_v2(computeInstance) + +def nvmlDeviceIsMigDeviceHandle(device): + c_isMigDevice = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceIsMigDeviceHandle") + ret = fn(device, byref(c_isMigDevice)) + _nvmlCheckReturn(ret) + return c_isMigDevice + +def nvmlDeviceGetGpuInstanceId(device): + c_gpuInstanceId = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuInstanceId") + ret = fn(device, byref(c_gpuInstanceId)) + _nvmlCheckReturn(ret) + return c_gpuInstanceId.value + +def nvmlDeviceGetComputeInstanceId(device): + c_computeInstanceId = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetComputeInstanceId") + ret = fn(device, byref(c_computeInstanceId)) + _nvmlCheckReturn(ret) + return c_computeInstanceId.value + +def nvmlDeviceGetMaxMigDeviceCount(device): + c_count = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMaxMigDeviceCount") + ret = fn(device, byref(c_count)) + _nvmlCheckReturn(ret) + return c_count.value + +def nvmlDeviceGetMigDeviceHandleByIndex(device, index): + c_index = c_uint(index) + migDevice = c_nvmlDevice_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMigDeviceHandleByIndex") + ret = fn(device, c_index, byref(migDevice)) + _nvmlCheckReturn(ret) + return migDevice + +def nvmlDeviceGetDeviceHandleFromMigDeviceHandle(migDevice): + device = c_nvmlDevice_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetDeviceHandleFromMigDeviceHandle") + ret = fn(migDevice, byref(device)) + _nvmlCheckReturn(ret) + return device + +def nvmlDeviceGetAttributes_v2(device): + c_attrs = c_nvmlDeviceAttributes() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetAttributes_v2") + ret = fn(device, byref(c_attrs)) + _nvmlCheckReturn(ret) + return c_attrs + +def nvmlDeviceGetAttributes(device): + return nvmlDeviceGetAttributes_v2(device) + +def nvmlDeviceGetRemappedRows(device): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetRemappedRows") + c_corr = c_uint() + c_unc = c_uint() + c_bpending = c_uint() + c_bfailure = c_uint() + ret = fn(device, byref(c_corr), byref(c_unc), byref(c_bpending), byref(c_bfailure)) + _nvmlCheckReturn(ret) + return (c_corr.value, c_unc.value, c_bpending.value, c_bfailure.value) + +def nvmlDeviceGetRowRemapperHistogram(device): + c_vals = c_nvmlRowRemapperHistogramValues() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetRowRemapperHistogram") + ret = fn(device, byref(c_vals)) + _nvmlCheckReturn(ret) + return c_vals + +def nvmlDeviceGetArchitecture(device): + arch = _nvmlDeviceArchitecture_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetArchitecture") + ret = fn(device, byref(arch)) + _nvmlCheckReturn(ret) + return arch.value + +def nvmlDeviceGetBusType(device): + c_busType = _nvmlBusType_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetBusType") + ret = fn(device, byref(c_busType)) + _nvmlCheckReturn(ret) + return c_busType.value + +def nvmlDeviceGetIrqNum(device): + c_irqNum = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetIrqNum") + ret = fn(device, byref(c_irqNum)) + _nvmlCheckReturn(ret) + return c_irqNum.value + +def nvmlDeviceGetNumGpuCores(device): + c_numCores = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetNumGpuCores") + ret = fn(device, byref(c_numCores)) + _nvmlCheckReturn(ret) + return c_numCores.value + +def nvmlDeviceGetPowerSource(device): + c_powerSource = _nvmlPowerSource_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerSource") + ret = fn(device, byref(c_powerSource)) + _nvmlCheckReturn(ret) + return c_powerSource.value + +def nvmlDeviceGetMemoryBusWidth(device): + c_memBusWidth = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMemoryBusWidth") + ret = fn(device, byref(c_memBusWidth)) + _nvmlCheckReturn(ret) + return c_memBusWidth.value + +def nvmlDeviceGetPcieLinkMaxSpeed(device): + c_speed = _nvmlPcieLinkMaxSpeed_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPcieLinkMaxSpeed") + ret = fn(device, byref(c_speed)) + _nvmlCheckReturn(ret) + return c_speed.value + +def nvmlDeviceGetAdaptiveClockInfoStatus(device): + c_adaptiveClockInfoStatus = _nvmlAdaptiveClockInfoStatus_t() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetAdaptiveClockInfoStatus") + ret = fn(device, byref(c_adaptiveClockInfoStatus)) + _nvmlCheckReturn(ret) + return c_adaptiveClockInfoStatus.value + +def nvmlDeviceGetPcieSpeed(device): + c_speed = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetPcieSpeed") + ret = fn(device, byref(c_speed)) + _nvmlCheckReturn(ret) + return c_speed.value + +def nvmlDeviceGetDynamicPstatesInfo(device, c_dynamicpstatesinfo): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetDynamicPstatesInfo"); + ret = fn(device, c_dynamicpstatesinfo) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceSetFanSpeed_v2(handle, index, speed): + fn = _nvmlGetFunctionPointer("nvmlDeviceSetFanSpeed_v2"); + ret = fn(handle, index, speed) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetThermalSettings(device, sensorindex, c_thermalsettings): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetThermalSettings"); + ret = fn(device, sensorindex, c_thermalsettings) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetMinMaxClockOfPState(device, type, pstate, minClockMHz, maxClockMHz): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMinMaxClockOfPState"); + ret = fn(device, _nvmlClockType_t(type), _nvmlClockType_t(pstate), minClockMHz, maxClockMHz) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetSupportedPerformanceStates(device): + pstates = [] + c_count = c_uint(NVML_MAX_GPU_PERF_PSTATES) + c_size = sizeof(c_uint)*c_count.value + + # NOTE: use 'c_uint' to represent the size of the nvmlPstate_t enumeration. + pstates_array = _nvmlPstates_t * c_count.value + c_pstates = pstates_array() + + fn = _nvmlGetFunctionPointer("nvmlDeviceGetSupportedPerformanceStates") + ret = fn(device, c_pstates, c_size) + _nvmlCheckReturn(ret) + + for value in c_pstates: + if value != NVML_PSTATE_UNKNOWN: + pstates.append(value) + + return pstates + +def nvmlDeviceGetGpcClkVfOffset(device): + offset = c_int32() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpcClkVfOffset") + ret = fn(device, byref(offset)) + _nvmlCheckReturn(ret) + return offset.value + +def nvmlDeviceSetGpcClkVfOffset(device, offset): + c_offset = c_int32(offset) + fn = _nvmlGetFunctionPointer("nvmlDeviceSetGpcClkVfOffset") + ret = fn(device, c_offset) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetGpcClkMinMaxVfOffset(device, minOffset, maxOffset): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpcClkMinMaxVfOffset") + ret = fn(device, minOffset, maxOffset) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetMemClkVfOffset(device): + offset = c_int32() + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMemClkVfOffset") + ret = fn(device, byref(offset)) + _nvmlCheckReturn(ret) + return offset.value + +def nvmlDeviceSetMemClkVfOffset(device, offset): + c_offset = c_int32(offset) + fn = _nvmlGetFunctionPointer("nvmlDeviceSetMemClkVfOffset") + ret = fn(device, c_offset) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceGetMemClkMinMaxVfOffset(device, minOffset, maxOffset): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetMemClkMinMaxVfOffset") + ret = fn(device, minOffset, maxOffset) + _nvmlCheckReturn(ret) + return ret + +## GPM ## +######### + +## Enums/defines + +#### GPM Metric Identifiers +NVML_GPM_METRIC_GRAPHICS_UTIL = 1 # Percentage of time any compute/graphics app was active on the GPU. 0.0 - 100.0 +NVML_GPM_METRIC_SM_UTIL = 2 # Percentage of SMs that were busy. 0.0 - 100.0 +NVML_GPM_METRIC_SM_OCCUPANCY = 3 # Percentage of warps that were active vs theoretical maximum. 0.0 - 100.0 +NVML_GPM_METRIC_INTEGER_UTIL = 4 # Percentage of time the GPU's SMs were doing integer operations. 0.0 - 100.0 +NVML_GPM_METRIC_ANY_TENSOR_UTIL = 5 # Percentage of time the GPU's SMs were doing ANY tensor operations. 0.0 - 100.0 +NVML_GPM_METRIC_DFMA_TENSOR_UTIL = 6 # Percentage of time the GPU's SMs were doing DFMA tensor operations. 0.0 - 100.0 +NVML_GPM_METRIC_HMMA_TENSOR_UTIL = 7 # Percentage of time the GPU's SMs were doing HMMA tensor operations. 0.0 - 100.0 +NVML_GPM_METRIC_IMMA_TENSOR_UTIL = 9 # Percentage of time the GPU's SMs were doing IMMA tensor operations. 0.0 - 100.0 +NVML_GPM_METRIC_DRAM_BW_UTIL = 10 # Percentage of DRAM bw used vs theoretical maximum. 0.0 - 100.0 +NVML_GPM_METRIC_FP64_UTIL = 11 # Percentage of time the GPU's SMs were doing non-tensor FP64 math. 0.0 - 100.0 +NVML_GPM_METRIC_FP32_UTIL = 12 # Percentage of time the GPU's SMs were doing non-tensor FP32 math. 0.0 - 100.0 +NVML_GPM_METRIC_FP16_UTIL = 13 # Percentage of time the GPU's SMs were doing non-tensor FP16 math. 0.0 - 100.0 +NVML_GPM_METRIC_PCIE_TX_PER_SEC = 20 # PCIe traffic from this GPU in MiB/sec +NVML_GPM_METRIC_PCIE_RX_PER_SEC = 21 # PCIe traffic to this GPU in MiB/sec +NVML_GPM_METRIC_NVDEC_0_UTIL = 30 # Percent utilization of NVDEC 0. 0.0 - 100.0 +NVML_GPM_METRIC_NVDEC_1_UTIL = 31 # Percent utilization of NVDEC 1. 0.0 - 100.0 +NVML_GPM_METRIC_NVDEC_2_UTIL = 32 # Percent utilization of NVDEC 2. 0.0 - 100.0 +NVML_GPM_METRIC_NVDEC_3_UTIL = 33 # Percent utilization of NVDEC 3. 0.0 - 100.0 +NVML_GPM_METRIC_NVDEC_4_UTIL = 34 # Percent utilization of NVDEC 4. 0.0 - 100.0 +NVML_GPM_METRIC_NVDEC_5_UTIL = 35 # Percent utilization of NVDEC 5. 0.0 - 100.0 +NVML_GPM_METRIC_NVDEC_6_UTIL = 36 # Percent utilization of NVDEC 6. 0.0 - 100.0 +NVML_GPM_METRIC_NVDEC_7_UTIL = 37 # Percent utilization of NVDEC 7. 0.0 - 100.0 +NVML_GPM_METRIC_NVJPG_0_UTIL = 40 # Percent utilization of NVJPG 0. 0.0 - 100.0 +NVML_GPM_METRIC_NVJPG_1_UTIL = 41 # Percent utilization of NVJPG 1. 0.0 - 100.0 +NVML_GPM_METRIC_NVJPG_2_UTIL = 42 # Percent utilization of NVJPG 2. 0.0 - 100.0 +NVML_GPM_METRIC_NVJPG_3_UTIL = 43 # Percent utilization of NVJPG 3. 0.0 - 100.0 +NVML_GPM_METRIC_NVJPG_4_UTIL = 44 # Percent utilization of NVJPG 4. 0.0 - 100.0 +NVML_GPM_METRIC_NVJPG_5_UTIL = 45 # Percent utilization of NVJPG 5. 0.0 - 100.0 +NVML_GPM_METRIC_NVJPG_6_UTIL = 46 # Percent utilization of NVJPG 6. 0.0 - 100.0 +NVML_GPM_METRIC_NVJPG_7_UTIL = 47 # Percent utilization of NVJPG 7. 0.0 - 100.0 +NVML_GPM_METRIC_NVOFA_0_UTIL = 50 # Percent utilization of NVOFA 0. 0.0 - 100.0 +NVML_GPM_METRIC_NVLINK_TOTAL_RX_PER_SEC = 60 # NvLink read bandwidth for all links in MiB/sec +NVML_GPM_METRIC_NVLINK_TOTAL_TX_PER_SEC = 61 # NvLink write bandwidth for all links in MiB/sec +NVML_GPM_METRIC_NVLINK_L0_RX_PER_SEC = 62 # NvLink read bandwidth for link 0 in MiB/sec +NVML_GPM_METRIC_NVLINK_L0_TX_PER_SEC = 63 # NvLink write bandwidth for link 0 in MiB/sec +NVML_GPM_METRIC_NVLINK_L1_RX_PER_SEC = 64 # NvLink read bandwidth for link 1 in MiB/sec +NVML_GPM_METRIC_NVLINK_L1_TX_PER_SEC = 65 # NvLink write bandwidth for link 1 in MiB/sec +NVML_GPM_METRIC_NVLINK_L2_RX_PER_SEC = 66 # NvLink read bandwidth for link 2 in MiB/sec +NVML_GPM_METRIC_NVLINK_L2_TX_PER_SEC = 67 # NvLink write bandwidth for link 2 in MiB/sec +NVML_GPM_METRIC_NVLINK_L3_RX_PER_SEC = 68 # NvLink read bandwidth for link 3 in MiB/sec +NVML_GPM_METRIC_NVLINK_L3_TX_PER_SEC = 69 # NvLink write bandwidth for link 3 in MiB/sec +NVML_GPM_METRIC_NVLINK_L4_RX_PER_SEC = 70 # NvLink read bandwidth for link 4 in MiB/sec +NVML_GPM_METRIC_NVLINK_L4_TX_PER_SEC = 71 # NvLink write bandwidth for link 4 in MiB/sec +NVML_GPM_METRIC_NVLINK_L5_RX_PER_SEC = 72 # NvLink read bandwidth for link 5 in MiB/sec +NVML_GPM_METRIC_NVLINK_L5_TX_PER_SEC = 73 # NvLink write bandwidth for link 5 in MiB/sec +NVML_GPM_METRIC_NVLINK_L6_RX_PER_SEC = 74 # NvLink read bandwidth for link 6 in MiB/sec +NVML_GPM_METRIC_NVLINK_L6_TX_PER_SEC = 75 # NvLink write bandwidth for link 6 in MiB/sec +NVML_GPM_METRIC_NVLINK_L7_RX_PER_SEC = 76 # NvLink read bandwidth for link 7 in MiB/sec +NVML_GPM_METRIC_NVLINK_L7_TX_PER_SEC = 77 # NvLink write bandwidth for link 7 in MiB/sec +NVML_GPM_METRIC_NVLINK_L8_RX_PER_SEC = 78 # NvLink read bandwidth for link 8 in MiB/sec +NVML_GPM_METRIC_NVLINK_L8_TX_PER_SEC = 79 # NvLink write bandwidth for link 8 in MiB/sec +NVML_GPM_METRIC_NVLINK_L9_RX_PER_SEC = 80 # NvLink read bandwidth for link 9 in MiB/sec +NVML_GPM_METRIC_NVLINK_L9_TX_PER_SEC = 81 # NvLink write bandwidth for link 9 in MiB/sec +NVML_GPM_METRIC_NVLINK_L10_RX_PER_SEC = 82 # NvLink read bandwidth for link 10 in MiB/sec +NVML_GPM_METRIC_NVLINK_L10_TX_PER_SEC = 83 # NvLink write bandwidth for link 10 in MiB/sec +NVML_GPM_METRIC_NVLINK_L11_RX_PER_SEC = 84 # NvLink read bandwidth for link 11 in MiB/sec +NVML_GPM_METRIC_NVLINK_L11_TX_PER_SEC = 85 # NvLink write bandwidth for link 11 in MiB/sec +NVML_GPM_METRIC_NVLINK_L12_RX_PER_SEC = 86 # NvLink read bandwidth for link 12 in MiB/sec +NVML_GPM_METRIC_NVLINK_L12_TX_PER_SEC = 87 # NvLink write bandwidth for link 12 in MiB/sec +NVML_GPM_METRIC_NVLINK_L13_RX_PER_SEC = 88 # NvLink read bandwidth for link 13 in MiB/sec +NVML_GPM_METRIC_NVLINK_L13_TX_PER_SEC = 89 # NvLink write bandwidth for link 13 in MiB/sec +NVML_GPM_METRIC_NVLINK_L14_RX_PER_SEC = 90 # NvLink read bandwidth for link 14 in MiB/sec +NVML_GPM_METRIC_NVLINK_L14_TX_PER_SEC = 91 # NvLink write bandwidth for link 14 in MiB/sec +NVML_GPM_METRIC_NVLINK_L15_RX_PER_SEC = 92 # NvLink read bandwidth for link 15 in MiB/sec +NVML_GPM_METRIC_NVLINK_L15_TX_PER_SEC = 93 # NvLink write bandwidth for link 15 in MiB/sec +NVML_GPM_METRIC_NVLINK_L16_RX_PER_SEC = 94 # NvLink read bandwidth for link 16 in MiB/sec +NVML_GPM_METRIC_NVLINK_L16_TX_PER_SEC = 95 # NvLink write bandwidth for link 16 in MiB/sec +NVML_GPM_METRIC_NVLINK_L17_RX_PER_SEC = 96 # NvLink read bandwidth for link 17 in MiB/sec +NVML_GPM_METRIC_NVLINK_L17_TX_PER_SEC = 97 # NvLink write bandwidth for link 17 in MiB/sec +NVML_GPM_METRIC_MAX = 98 + +## Structs + +class c_nvmlUnitInfo_t(_PrintableStructure): + _fields_ = [ + ('name', c_char * 96), + ('id', c_char * 96), + ('serial', c_char * 96), + ('firmwareVersion', c_char * 96), + ] + +class struct_c_nvmlGpmSample_t(Structure): + pass # opaque handle +c_nvmlGpmSample_t = POINTER(struct_c_nvmlGpmSample_t) + +class c_metricInfo_t(Structure): + _fields_ = [ + ("shortName", c_char_p), + ("longName", c_char_p), + ("unit", c_char_p), + ] + +class c_nvmlGpmMetric_t(_PrintableStructure): + _fields_ = [ + ('metricId', c_uint), + ('nvmlReturn', _nvmlReturn_t), + ('value', c_double), + ('metricInfo', c_metricInfo_t) + ] + +class c_nvmlGpmMetricsGet_t(_PrintableStructure): + _fields_ = [ + ('version', c_uint), + ('numMetrics', c_uint), + ('sample1', c_nvmlGpmSample_t), + ('sample2', c_nvmlGpmSample_t), + ('metrics', c_nvmlGpmMetric_t * NVML_GPM_METRIC_MAX) + ] + +NVML_GPM_METRICS_GET_VERSION = 1 + +class c_nvmlGpmSupport_t(_PrintableStructure): + _fields_ = [ + ('version', c_uint), + ('isSupportedDevice', c_uint), + ] + +NVML_GPM_SUPPORT_VERSION = 1 + +## Functions + +def nvmlGpmMetricsGet(metricsGet): + fn = _nvmlGetFunctionPointer("nvmlGpmMetricsGet") + ret = fn(byref(metricsGet)) + _nvmlCheckReturn(ret) + return metricsGet + +def nvmlGpmSampleFree(gpmSample): + fn = _nvmlGetFunctionPointer("nvmlGpmSampleFree") + ret = fn(gpmSample) + _nvmlCheckReturn(ret) + return + +def nvmlGpmSampleAlloc(): + gpmSample = c_nvmlGpmSample_t() + fn = _nvmlGetFunctionPointer("nvmlGpmSampleAlloc") + ret = fn(byref(gpmSample)) + _nvmlCheckReturn(ret) + return gpmSample + +def nvmlGpmSampleGet(device, gpmSample): + fn = _nvmlGetFunctionPointer("nvmlGpmSampleGet") + ret = fn(device, gpmSample) + _nvmlCheckReturn(ret) + return gpmSample + +def nvmlGpmMigSampleGet(device, gpuInstanceId, gpmSample): + fn = _nvmlGetFunctionPointer("nvmlGpmMigSampleGet") + ret = fn(device, gpuInstanceId, gpmSample) + _nvmlCheckReturn(ret) + return gpmSample + +def nvmlGpmQueryDeviceSupport(device): + gpmSupport = c_nvmlGpmSupport_t() + gpmSupport.version = NVML_GPM_SUPPORT_VERSION + fn = _nvmlGetFunctionPointer("nvmlGpmQueryDeviceSupport") + ret = fn(device, byref(gpmSupport)) + _nvmlCheckReturn(ret) + return gpmSupport + +## CCU ## +######### + +## Enums/defines + +#### CCU Stream State +NVML_COUNTER_COLLECTION_UNIT_STREAM_STATE_DISABLE = 0 +NVML_COUNTER_COLLECTION_UNIT_STREAM_STATE_ENABLE = 1 + +## Functions + +def nvmlDeviceCcuSetStreamState(device, state): + c_state = c_uint(state) + fn = _nvmlGetFunctionPointer("nvmlDeviceCcuSetStreamState") + ret = fn(device, c_state) + _nvmlCheckReturn(ret) + return ret + +def nvmlDeviceCcuGetStreamState(device): + c_state = c_uint() + fn = _nvmlGetFunctionPointer("nvmlDeviceCcuGetStreamState") + ret = fn(device, byref(c_state)) + _nvmlCheckReturn(ret) + return c_state.value + +# Low Power Structure and Function + +class c_nvmlNvLinkPowerThres_t(Structure): + _fields_ = [ + ("lowPwrThreshold", c_uint), + ] + +def nvmlDeviceSetNvLinkDeviceLowPowerThreshold(device, l1threshold): + c_info = c_nvmlNvLinkPowerThres_t() + c_info.lowPwrThreshold = l1threshold + fn = _nvmlGetFunctionPointer("nvmlDeviceSetNvLinkDeviceLowPowerThreshold") + ret = fn(device, byref(c_info)) + _nvmlCheckReturn(ret) + return ret + +_nvmlGpuFabricState_t = c_uint +NVML_GPU_FABRIC_STATE_NOT_SUPPORTED = 0 +NVML_GPU_FABRIC_STATE_NOT_STARTED = 1 +NVML_GPU_FABRIC_STATE_IN_PROGRESS = 2 +NVML_GPU_FABRIC_STATE_COMPLETED = 3 + +class c_nvmlGpuFabricInfo_t(_PrintableStructure): + _fields_ = [ + ("clusterUuid", c_char * NVML_DEVICE_UUID_BUFFER_SIZE), + ("status", _nvmlReturn_t), + ("partitionId", c_uint32), + ("state", _nvmlGpuFabricState_t) + ] + +def nvmlDeviceGetGpuFabricInfo(device, gpuFabricInfo): + fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuFabricInfo"); + ret = fn(device, gpuFabricInfo) + _nvmlCheckReturn(ret) + return ret + diff --git a/pynvml/smi.py b/pynvml/smi.py new file mode 100755 index 0000000..a2ea38e --- /dev/null +++ b/pynvml/smi.py @@ -0,0 +1,2996 @@ +# ============================================================================ # +# Copyright (c) 2011-2021, NVIDIA Corporation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the NVIDIA Corporation nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# ============================================================================ # + +""" +nvidia_smi + +Sample code that attempts to reproduce the output of nvidia-smi -q -x +For many cases the output should match. +Each query parameter is documented within nvdia-smi --help-query-gpu + +From Code: +DeviceQuery() +DeviceQuery("--help") +DeviceQuery("--help-query-gpu") +DeviceQuery("pci.bus_id,memory.total,memory.free") +DeviceQuery([NVSMI_PCI_BUS_ID, NVSMI_MEMORY_TOTAL, NVSMI_MEMORY_FREE]) + +XmlDeviceQuery() +XmlDeviceQuery("--help") +XmlDeviceQuery("--help-query-gpu") +""" + +from pynvml.nvml import * +import datetime +import collections +import time +from threading import Thread + +## ========================================================================== ## +## ## +## Enumerations ## +## ## +## ========================================================================== ## + +#Details and descriptions for enumerations in help_query_gpu.txt +NVSMI_ALL = -1 + +NVSMI_TIMESTAMP = 1 +NVSMI_DRIVER_VERSION = 2 +NVSMI_COUNT = 3 +NVSMI_NAME = 4 +NVSMI_SERIALNUMBER = 5 +NVSMI_UUID = 6 +NVSMI_PCI_BUS_ID = 7 +NVSMI_PCI_DOMAIN = 8 +NVSMI_PCI_BUS = 9 +NVSMI_PCI_DEVICE = 10 +NVSMI_PCI_DEVICE_ID = 11 +NVSMI_PCI_SUBDEVICE_ID = 12 +NVSMI_PCI_LINK_GEN_CUR = 13 +NVSMI_PCI_LINK_GEN_MAX = 14 +NVSMI_PCI_LINK_WIDTH_CUR = 15 +NVSMI_PCI_LINK_WIDTH_MAX = 16 +NVSMI_INDEX = 17 +NVSMI_DISPLAY_MODE = 18 +NVSMI_DISPLAY_ACTIVE = 19 +NVSMI_PERSISTENCE_MODE = 20 +NVSMI_ACCT_MODE = 21 +NVSMI_ACCT_BUFFER_SIZE = 22 +NVSMI_DRIVER_MODEL_CUR = 23 +NVSMI_DRIVER_MODEL_PENDING = 24 +NVSMI_VBIOS_VER = 25 +NVSMI_BOARD_ID = 26 + +NVSMI_INFOROM_IMG = 190 +NVSMI_INFOROM_OEM = 191 +NVSMI_INFOROM_ECC = 192 +NVSMI_INFOROM_PWR = 193 + +NVSMI_GOM_CUR = 30 +NVSMI_GOM_PENDING = 31 + +NVSMI_FAN_SPEED = 32 +NVSMI_PSTATE = 33 + +NVSMI_MEMORY_TOTAL = 50 +NVSMI_MEMORY_FREE = 51 +NVSMI_MEMORY_USED = 52 +NVSMI_COMPUTE_MODE = 53 +NVSMI_MEMORY_BAR1 = 54 + +NVSMI_UTILIZATION_GPU = 60 +NVSMI_UTILIZATION_MEM = 61 +NVSMI_UTILIZATION_ENCODER = 62 +NVSMI_UTILIZATION_DECODER = 63 + +NVSMI_ENCODER_STATS_SESSIONCOUNT = 260 +NVSMI_ENCODER_STATS_AVG_EPS = 261 +NVSMI_ENCODER_STATS_AVG_LATENCY = 262 + +NVSMI_ECC_MODE_CUR = 70 +NVSMI_ECC_MODE_PENDING = 71 + +NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DEV_MEM = 80 +NVSMI_ECC_ERROR_CORRECTED_VOLATILE_REGFILE = 81 +NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L1CACHE = 82 +NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L2CACHE = 83 +NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE = 84 +NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TOTAL = 85 +NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DRAM = 86 +NVSMI_ECC_ERROR_CORRECTED_VOLATILE_SRAM = 87 +NVSMI_ECC_ERROR_CORRECTED_VOLATILE_CBU = 88 + +NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DEV_MEM = 90 +NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_REGFILE = 91 +NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L1CACHE = 92 +NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L2CACHE = 93 +NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TEXTURE = 94 +NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TOTAL = 95 +NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DRAM = 96 +NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_CBU = 97 +NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_SRAM = 98 + +NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_DEV_MEM = 100 +NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_REGFILE = 101 +NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_L1CACHE = 102 +NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_L2CACHE = 103 +NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_TEXTURE = 104 +NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_TOTAL = 105 +NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_DRAM = 106 +NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_CBU = 107 +NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_SRAM = 108 + +NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_DEV_MEM = 110 +NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_REGFILE = 111 +NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_L1CACHE = 112 +NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_L2CACHE = 113 +NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_TEXTURE = 114 +NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_TOTAL = 115 +NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_DRAM = 116 +NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_CBU = 117 +NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_SRAM = 118 + +NVSMI_RETIREDPAGES_SINGLE_BIT_ECC_COUNT = 120 +NVSMI_RETIREDPAGES_DOUBLE_BIT_ECC_COUNT = 121 +NVSMI_RETIREDPAGES_PENDING = 122 + +NVSMI_CLOCK_THROTTLE_REASONS_SUPPORTED = 170 +NVSMI_CLOCK_THROTTLE_REASONS_ACTIVE = 171 +NVSMI_CLOCK_THROTTLE_REASONS_IDLE = 172 +NVSMI_CLOCK_THROTTLE_REASONS_APP_SETTING = 173 +NVSMI_CLOCK_THROTTLE_REASONS_SW_PWR_CAP = 174 +NVSMI_CLOCK_THROTTLE_REASONS_HW_SLOWDOWN = 175 + +NVSMI_CLOCK_THROTTLE_REASONS_HW_THERMAL_SLOWDOWN = 176 +NVSMI_CLOCK_THROTTLE_REASONS_HW_PWR_BRAKE_SLOWDOWN = 177 +NVSMI_CLOCK_THROTTLE_REASONS_SW_THERMAL_SLOWDOWN = 178 +NVSMI_CLOCK_THROTTLE_REASONS_SYNC_BOOST = 179 + +NVSMI_TEMPERATURE_GPU = 130 +NVSMI_TEMPERATURE_MEMORY = 131 + +NVSMI_POWER_MGMT = 140 +NVSMI_POWER_DRAW = 141 +NVSMI_POWER_LIMIT = 142 +NVSMI_POWER_LIMIT_ENFORCED = 143 +NVSMI_POWER_LIMIT_DEFAULT = 144 +NVSMI_POWER_LIMIT_MIN = 145 +NVSMI_POWER_LIMIT_MAX = 146 + +NVSMI_CLOCKS_GRAPHICS_CUR = 150 +NVSMI_CLOCKS_SM_CUR = 151 +NVSMI_CLOCKS_MEMORY_CUR = 152 +NVSMI_CLOCKS_VIDEO_CUR = 153 +NVSMI_CLOCKS_APPL_GRAPHICS = 154 +NVSMI_CLOCKS_APPL_MEMORY = 155 +NVSMI_CLOCKS_APPL_GRAPHICS_DEFAULT = 156 +NVSMI_CLOCKS_APPL_MEMORY_DEFAULT = 157 +NVSMI_CLOCKS_GRAPHICS_MAX = 158 +NVSMI_CLOCKS_SM_MAX = 159 +NVSMI_CLOCKS_MEMORY_MAX = 160 + +NVSMI_COMPUTE_APPS = 200 +NVSMI_ACCOUNTED_APPS = 201 +NVSMI_CLOCKS_POLICY = 202 +NVSMI_CLOCKS_SUPPORTED = 203 + +NVSMI_MIG_MODE_CURRENT = 210 +NVSMI_MIG_MODE_PENDING = 211 + +#Details and descriptions for enumerations in help_query_gpu.txt +NVSMI_QUERY_GPU = { + "timestamp" : NVSMI_TIMESTAMP, + "driver_version" : NVSMI_DRIVER_VERSION, + "count" : NVSMI_COUNT, + "name" : NVSMI_NAME, + "gpu_name" : NVSMI_NAME, + "serial" : NVSMI_SERIALNUMBER, + "gpu_serial" : NVSMI_SERIALNUMBER, + "uuid" : NVSMI_UUID, + "gpu_uuid" : NVSMI_UUID, + "pci.bus_id" : NVSMI_PCI_BUS_ID, + "gpu_bus_id" : NVSMI_PCI_BUS_ID, + "pci.domain" : NVSMI_PCI_DOMAIN, + "pci.bus" : NVSMI_PCI_BUS, + "pci.device" : NVSMI_PCI_DEVICE, + "pci.device_id" : NVSMI_PCI_DEVICE_ID, + "pci.sub_device_id" : NVSMI_PCI_SUBDEVICE_ID, + "pcie.link.gen.current" : NVSMI_PCI_LINK_GEN_CUR, + "pcie.link.gen.max" : NVSMI_PCI_LINK_GEN_MAX, + "pcie.link.width.current" : NVSMI_PCI_LINK_WIDTH_CUR, + "pcie.link.width.max" : NVSMI_PCI_LINK_WIDTH_MAX, + "index" : NVSMI_INDEX, + "display_mode" : NVSMI_DISPLAY_MODE, + "display_active" : NVSMI_DISPLAY_ACTIVE, + "persistence_mode" : NVSMI_PERSISTENCE_MODE, + "accounting.mode" : NVSMI_ACCT_MODE, + "accounting.buffer_size" : NVSMI_ACCT_BUFFER_SIZE, + "driver_model.current" : NVSMI_DRIVER_MODEL_CUR, + "driver_model.pending" : NVSMI_DRIVER_MODEL_PENDING, + "vbios_version" : NVSMI_VBIOS_VER, + "inforom.img" : NVSMI_INFOROM_IMG, + "inforom.image" : NVSMI_INFOROM_IMG, + "inforom.oem" : NVSMI_INFOROM_OEM, + "inforom.ecc" : NVSMI_INFOROM_ECC, + "inforom.pwr" : NVSMI_INFOROM_PWR, + "inforom.power" : NVSMI_INFOROM_PWR, + "gom.current" : NVSMI_GOM_CUR, + "gpu_operation_mode.current" : NVSMI_GOM_CUR, + "gom.pending" : NVSMI_GOM_PENDING, + "gpu_operation_mode.pending" : NVSMI_GOM_PENDING, + "fan.speed" : NVSMI_FAN_SPEED, + "pstate" : NVSMI_PSTATE, + "clocks_throttle_reasons.supported" : NVSMI_CLOCK_THROTTLE_REASONS_SUPPORTED, + "clocks_throttle_reasons.active" : NVSMI_CLOCK_THROTTLE_REASONS_ACTIVE, + "clocks_throttle_reasons.gpu_idle" : NVSMI_CLOCK_THROTTLE_REASONS_IDLE, + "clocks_throttle_reasons.applications_clocks_setting" : NVSMI_CLOCK_THROTTLE_REASONS_APP_SETTING, + "clocks_throttle_reasons.sw_power_cap" : NVSMI_CLOCK_THROTTLE_REASONS_SW_PWR_CAP, + "clocks_throttle_reasons.hw_slowdown" : NVSMI_CLOCK_THROTTLE_REASONS_HW_SLOWDOWN, + "clocks_throttle_reasons.hw_thermal_slowdown" : NVSMI_CLOCK_THROTTLE_REASONS_HW_THERMAL_SLOWDOWN, + "clocks_throttle_reasons.hw_power_brake_slowdown" : NVSMI_CLOCK_THROTTLE_REASONS_HW_PWR_BRAKE_SLOWDOWN, + "clocks_throttle_reasons.sw_thermal_slowdown" : NVSMI_CLOCK_THROTTLE_REASONS_SW_THERMAL_SLOWDOWN, + "clocks_throttle_reasons.sync_boost" : NVSMI_CLOCK_THROTTLE_REASONS_SYNC_BOOST, + "memory.total" : NVSMI_MEMORY_TOTAL, + "memory.used" : NVSMI_MEMORY_USED, + "memory.free" : NVSMI_MEMORY_FREE, + "compute_mode" : NVSMI_COMPUTE_MODE, + "utilization.gpu" : NVSMI_UTILIZATION_GPU, + "utilization.memory" : NVSMI_UTILIZATION_MEM, + "encoder.stats.sessionCount" : NVSMI_ENCODER_STATS_SESSIONCOUNT, + "encoder.stats.averageFps" : NVSMI_ENCODER_STATS_AVG_EPS, + "encoder.stats.averageLatency" : NVSMI_ENCODER_STATS_AVG_LATENCY, + "ecc.mode.current" : NVSMI_ECC_MODE_CUR, + "ecc.mode.pending" : NVSMI_ECC_MODE_PENDING, + "ecc.errors.corrected.volatile.device_memory" : NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DEV_MEM, + "ecc.errors.corrected.volatile.register_file" : NVSMI_ECC_ERROR_CORRECTED_VOLATILE_REGFILE, + "ecc.errors.corrected.volatile.l1_cache" : NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L1CACHE, + "ecc.errors.corrected.volatile.l2_cache" : NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L2CACHE, + "ecc.errors.corrected.volatile.texture_memory" : NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE, + "ecc.errors.corrected.volatile.dram" : NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DRAM, + "ecc.errors.corrected.volatile.sram" : NVSMI_ECC_ERROR_CORRECTED_VOLATILE_SRAM, + "ecc.errors.corrected.volatile.cbu" : NVSMI_ECC_ERROR_CORRECTED_VOLATILE_CBU, + "ecc.errors.corrected.volatile.total" : NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TOTAL, + "ecc.errors.corrected.aggregate.device_memory" : NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DEV_MEM, + "ecc.errors.corrected.aggregate.register_file" : NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_REGFILE, + "ecc.errors.corrected.aggregate.l1_cache" : NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L1CACHE, + "ecc.errors.corrected.aggregate.l2_cache" : NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L2CACHE, + "ecc.errors.corrected.aggregate.texture_memory" : NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TEXTURE, + "ecc.errors.corrected.aggregate.dram" : NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DRAM, + "ecc.errors.corrected.aggregate.cbu" : NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_CBU, + "ecc.errors.corrected.aggregate.sram" : NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_SRAM, + "ecc.errors.corrected.aggregate.total" : NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TOTAL, + "ecc.errors.uncorrected.volatile.device_memory" : NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_DEV_MEM, + "ecc.errors.uncorrected.volatile.register_file" : NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_REGFILE, + "ecc.errors.uncorrected.volatile.l1_cache" : NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_L1CACHE, + "ecc.errors.uncorrected.volatile.l2_cache" : NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_L2CACHE, + "ecc.errors.uncorrected.volatile.texture_memory" : NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_TEXTURE, + "ecc.errors.uncorrected.volatile.dram" : NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_DRAM, + "ecc.errors.uncorrected.volatile.cbu" : NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_CBU, + "ecc.errors.uncorrected.volatile.sram" : NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_SRAM, + "ecc.errors.uncorrected.volatile.total" : NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_TOTAL, + "ecc.errors.uncorrected.aggregate.device_memory" : NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_DEV_MEM, + "ecc.errors.uncorrected.aggregate.register_file" : NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_REGFILE, + "ecc.errors.uncorrected.aggregate.l1_cache" : NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_L1CACHE, + "ecc.errors.uncorrected.aggregate.l2_cache" : NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_L2CACHE, + "ecc.errors.uncorrected.aggregate.texture_memory" : NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_TEXTURE, + "ecc.errors.uncorrected.aggregate.dram" : NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_DRAM, + "ecc.errors.uncorrected.aggregate.cbu" : NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_CBU, + "ecc.errors.uncorrected.aggregate.sram" : NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_SRAM, + "ecc.errors.uncorrected.aggregate.total" : NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_TOTAL, + "retired_pages.single_bit_ecc.count" : NVSMI_RETIREDPAGES_SINGLE_BIT_ECC_COUNT, + "retired_pages.sbe" : NVSMI_RETIREDPAGES_SINGLE_BIT_ECC_COUNT, + "retired_pages.double_bit.count" : NVSMI_RETIREDPAGES_DOUBLE_BIT_ECC_COUNT, + "retired_pages.dbe" : NVSMI_RETIREDPAGES_DOUBLE_BIT_ECC_COUNT, + "retired_pages.pending" : NVSMI_RETIREDPAGES_PENDING, + "temperature.gpu" : NVSMI_TEMPERATURE_GPU, + "temperature.memory" : NVSMI_TEMPERATURE_MEMORY, + "power.management" : NVSMI_POWER_MGMT, + "power.draw" : NVSMI_POWER_DRAW, + "power.limit" : NVSMI_POWER_LIMIT, + "enforced.power.limit" : NVSMI_POWER_LIMIT_ENFORCED, + "power.default_limit" : NVSMI_POWER_LIMIT_DEFAULT, + "power.min_limit" : NVSMI_POWER_LIMIT_MIN, + "power.max_limit" : NVSMI_POWER_LIMIT_MAX, + "clocks.current.graphics" : NVSMI_CLOCKS_GRAPHICS_CUR, + "clocks.gr" : NVSMI_CLOCKS_GRAPHICS_CUR, + "clocks.current.sm" : NVSMI_CLOCKS_SM_CUR, + "clocks.sm" : NVSMI_CLOCKS_SM_CUR, + "clocks.current.memory" : NVSMI_CLOCKS_MEMORY_CUR, + "clocks.mem" : NVSMI_CLOCKS_MEMORY_CUR, + "clocks.current.video" : NVSMI_CLOCKS_VIDEO_CUR, + "clocks.video" : NVSMI_CLOCKS_VIDEO_CUR, + "clocks.applications.graphics" : NVSMI_CLOCKS_APPL_GRAPHICS, + "clocks.applications.gr" : NVSMI_CLOCKS_APPL_GRAPHICS, + "clocks.applications.memory" : NVSMI_CLOCKS_APPL_MEMORY, + "clocks.applications.mem" : NVSMI_CLOCKS_APPL_MEMORY, + "clocks.default_applications.graphics" : NVSMI_CLOCKS_APPL_GRAPHICS_DEFAULT, + "clocks.default_applications.gr" : NVSMI_CLOCKS_APPL_GRAPHICS_DEFAULT, + "clocks.default_applications.memory" : NVSMI_CLOCKS_APPL_MEMORY_DEFAULT, + "clocks.default_applications.mem" : NVSMI_CLOCKS_APPL_MEMORY_DEFAULT, + "clocks.max.graphics" : NVSMI_CLOCKS_GRAPHICS_MAX, + "clocks.max.gr" : NVSMI_CLOCKS_GRAPHICS_MAX, + "clocks.max.sm" : NVSMI_CLOCKS_SM_MAX, + "clocks.max.sm" : NVSMI_CLOCKS_SM_MAX, + "clocks.max.memory" : NVSMI_CLOCKS_MEMORY_MAX, + "clocks.max.mem" : NVSMI_CLOCKS_MEMORY_MAX, + "supported-clocks" : NVSMI_CLOCKS_SUPPORTED, + "compute-apps" : NVSMI_COMPUTE_APPS, + "accounted-apps" : NVSMI_ACCOUNTED_APPS, + "clocks" : NVSMI_CLOCKS_POLICY, + "mig.mode.current" : NVSMI_MIG_MODE_CURRENT, + "mig.mode.pending" : NVSMI_MIG_MODE_PENDING, +} + +NVSMI_BRAND_NAMES = {NVML_BRAND_UNKNOWN : "Unknown", + NVML_BRAND_QUADRO : "Quadro", + NVML_BRAND_TESLA : "Tesla", + NVML_BRAND_NVS : "NVS", + NVML_BRAND_GRID : "Grid", + NVML_BRAND_GEFORCE : "GeForce", + NVML_BRAND_TITAN : "Titan", + NVML_BRAND_NVIDIA_VAPPS : "NVIDIA Virtual Applications", + NVML_BRAND_NVIDIA_VPC : "NVIDIA Virtual PC", + NVML_BRAND_NVIDIA_VCS : "NVIDIA Virtual Compute Server", + NVML_BRAND_NVIDIA_VWS : "NVIDIA RTX Virtual Workstation", + NVML_BRAND_NVIDIA_VGAMING : "NVIDIA vGaming", + NVML_BRAND_QUADRO_RTX : "Quadro RTX", + NVML_BRAND_NVIDIA_RTX : "NVIDIA RTX", + NVML_BRAND_NVIDIA : "NVIDIA", + NVML_BRAND_GEFORCE_RTX : "Geforce RTX", + NVML_BRAND_TITAN_RTX : "Titan RTX", +} + +## ========================================================================== ## +## ## +## nvidia_smi Class ## +## ## +## ========================================================================== ## + +class nvidia_smi: + __instance = None + __handles = None + + class loop_async: + __last_result = None + __task = None + __abort = False + __callback_chain = None + + def __init__(self, time_in_milliseconds=1, filter=None, callback=None): + self.__abort = False + self.__callback_chain = callback + + self.__task = Thread(target = nvidia_smi.loop_async.__loop_task, args = (self, time_in_milliseconds, filter, nvidia_smi.loop_async.__callback)) + self.__task.start() + + def __del__(self): + self.__abort = True + self.__callback_chain = None + + @staticmethod + def __loop_task(async_results, time_in_milliseconds=1, filter=None, callback=None): + delay_seconds = time_in_milliseconds / 1000 + nvsmi = nvidia_smi.getInstance() + + while async_results.is_aborted() == False: + results = nvsmi.DeviceQuery(filter) + async_results.__last_results = results + if (callback is not None): + callback(async_results, results) + + time.sleep(delay_seconds) + + def __callback(self, result): + self.__last_result = result + if (self.__callback_chain is not None): + self.__callback_chain(self, result) + + def cancel(self): + self.__abort = True + if (self.__task is not None): + self.__task.join() + + def is_aborted(self): + return self.__abort + + def result(self): + return self.__last_result + + @staticmethod + def getInstance(): + ''' Static access method. ''' + if nvidia_smi.__instance == None: + nvidia_smi() + return nvidia_smi.__instance + + @staticmethod + def loop(time_in_milliseconds=1, filter=None, callback=None): + return nvidia_smi.loop_async(time_in_milliseconds, filter, callback) + + def __init__(self): + ''' Virtually private constructor. ''' + if nvidia_smi.__instance != None: + raise Exception("This class is a singleton, use getInstance()") + else: + nvidia_smi.__instance = self + + if nvidia_smi.__handles == None: + nvidia_smi.__handles = nvidia_smi.__initialize_nvml() + + @staticmethod + def __initialize_nvml(): + ''' Initialize NVML bindings. ''' + nvmlInit() + deviceCount = nvmlDeviceGetCount() + handles = {} + for i in range(0, deviceCount): + handles[i] = nvmlDeviceGetHandleByIndex(i) + return handles + + def __del__(self): + if (nvidia_smi.__instance != None) and (nvidia_smi.__instance == self): + del(nvidia_smi.__instance) + nvidia_smi.__instance = None + nvidia_smi.__handles = None + nvmlShutdown() + + # + # Helper functions + # + + @staticmethod + def __fromDeviceQueryString(queryString): + parameters = queryString.split(",") + values = [] + for p in parameters: + ps = p.strip() + if (ps in NVSMI_QUERY_GPU): + values.append(NVSMI_QUERY_GPU[ps]) + + return values + + + @staticmethod + def __xmlGetEccByType(handle, counterType, errorType): + strResult = '' + + try: + deviceMemory = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_DEVICE_MEMORY) + except NVMLError as err: + deviceMemory = nvidia_smi.__handleError(err) + strResult += ' ' + nvidia_smi.__toString(deviceMemory) + '\n' + + try: + registerFile = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_DRAM) + except NVMLError as err: + registerFile = nvidia_smi.__handleError(err) + + strResult += ' ' + nvidia_smi.__toString(registerFile) + '\n' + + try: + registerFile = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_REGISTER_FILE) + except NVMLError as err: + registerFile = nvidia_smi.__handleError(err) + + strResult += ' ' + nvidia_smi.__toString(registerFile) + '\n' + + try: + l1Cache = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_L1_CACHE) + except NVMLError as err: + l1Cache = nvidia_smi.__handleError(err) + strResult += ' ' + nvidia_smi.__toString(l1Cache) + '\n' + + try: + l2Cache = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_L2_CACHE) + except NVMLError as err: + l2Cache = nvidia_smi.__handleError(err) + strResult += ' ' + nvidia_smi.__toString(l2Cache) + '\n' + + try: + textureMemory = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_TEXTURE_MEMORY) + except NVMLError as err: + textureMemory = nvidia_smi.__handleError(err) + strResult += ' ' + nvidia_smi.__toString(textureMemory) + '\n' + + try: + registerFile = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_CBU) + except NVMLError as err: + registerFile = nvidia_smi.__handleError(err) + + strResult += ' ' + nvidia_smi.__toString(registerFile) + '\n' + + try: + registerFile = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_SRAM) + except NVMLError as err: + registerFile = nvidia_smi.__handleError(err) + + strResult += ' ' + nvidia_smi.__toString(registerFile) + '\n' + + try: + count = nvidia_smi.__toString(nvmlDeviceGetTotalEccErrors(handle, errorType, counterType)) + except NVMLError as err: + count = nvidia_smi.__handleError(err) + strResult += ' ' + count + '\n' + + return strResult + + @staticmethod + def __GetEccByType(handle, counterType, errorType): + strResult = '' + + eccByType = {} + try: + deviceMemory = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_DEVICE_MEMORY) + except NVMLError as err: + deviceMemory = nvidia_smi.__handleError(err) + + eccByType['device_memory'] = deviceMemory + + try: + deviceMemory = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_DRAM) + except NVMLError as err: + deviceMemory = nvidia_smi.__handleError(err) + + eccByType['dram'] = deviceMemory + + try: + registerFile = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_REGISTER_FILE) + except NVMLError as err: + registerFile = nvidia_smi.__handleError(err) + + eccByType['register_file'] = registerFile + + try: + l1Cache = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_L1_CACHE) + except NVMLError as err: + l1Cache = nvidia_smi.__handleError(err) + eccByType['l1_cache'] = l1Cache + + try: + l2Cache = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_L2_CACHE) + except NVMLError as err: + l2Cache = nvidia_smi.__handleError(err) + eccByType['l2_cache'] = l2Cache + + try: + textureMemory = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_TEXTURE_MEMORY) + except NVMLError as err: + textureMemory = nvidia_smi.__handleError(err) + eccByType['texture_memory'] = textureMemory + + try: + deviceMemory = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_CBU) + except NVMLError as err: + deviceMemory = nvidia_smi.__handleError(err) + + eccByType['cbu'] = deviceMemory + + try: + deviceMemory = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType, + NVML_MEMORY_LOCATION_SRAM) + except NVMLError as err: + deviceMemory = nvidia_smi.__handleError(err) + + eccByType['sram'] = deviceMemory + + try: + count = nvidia_smi.__toString(nvmlDeviceGetTotalEccErrors(handle, errorType, counterType)) + except NVMLError as err: + count = nvidia_smi.__handleError(err) + eccByType['total'] = count + + return eccByType + + @staticmethod + def __xmlGetEccByCounter(handle, counterType, filter): + eccByCounter = '' + if (NVSMI_ALL in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TOTAL in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TOTAL in filter): + eccByCounter += ' \n' + eccByCounter += nvidia_smi.__toString(nvidia_smi.__xmlGetEccByType(handle, counterType, NVML_MEMORY_ERROR_TYPE_CORRECTED)) + eccByCounter += ' \n' + + if (NVSMI_ALL in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TOTAL in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TOTAL in filter): + eccByCounter += ' \n' + eccByCounter += nvidia_smi.__toString(nvidia_smi.__xmlGetEccByType(handle, counterType, NVML_MEMORY_ERROR_TYPE_UNCORRECTED)) + eccByCounter += ' \n' + + return eccByCounter + + @staticmethod + def __GetEccByCounter(handle, counterType, filter): + eccByCounter = {} + + if (NVSMI_ALL in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TOTAL in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TOTAL in filter): + eccByCounter['single_bit'] = nvidia_smi.__GetEccByType(handle, counterType, NVML_MEMORY_ERROR_TYPE_CORRECTED) + + if (NVSMI_ALL in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TOTAL in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TOTAL in filter): + eccByCounter['double_bit'] = nvidia_smi.__GetEccByType(handle, counterType, NVML_MEMORY_ERROR_TYPE_UNCORRECTED) + + return eccByCounter + + @staticmethod + def __xmlGetEcc(handle, filter): + ecc = '' + includeEcc = False + if (NVSMI_ALL in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TOTAL in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_DEV_MEM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_REGFILE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_L1CACHE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_L2CACHE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_DRAM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_SRAM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_CBU in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_TOTAL in filter ): + ecc += ' \n' + ecc += nvidia_smi.__toString(nvidia_smi.__xmlGetEccByCounter(handle, NVML_VOLATILE_ECC, filter)) + ecc += ' \n' + includeEcc = True + + if (NVSMI_ALL in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TOTAL in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_DEV_MEM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_REGFILE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_L1CACHE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_L2CACHE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_TEXTURE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_DRAM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_SRAM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_CBU in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_TOTAL in filter ): + ecc += ' \n' + ecc += nvidia_smi.__toString(nvidia_smi.__xmlGetEccByCounter(handle, NVML_AGGREGATE_ECC, filter)) + ecc += ' \n' + includeEcc = True + + return ecc if len(ecc) > 0 else None, includeEcc + + @staticmethod + def __GetEcc( handle, filter): + ecc = {} + includeEcc = False + if (NVSMI_ALL in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TOTAL in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_DEV_MEM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_REGFILE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_L1CACHE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_L2CACHE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_TEXTURE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_DRAM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_SRAM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_CBU in filter or + NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_TOTAL in filter ): + ecc['volatile'] = nvidia_smi.__GetEccByCounter(handle, NVML_VOLATILE_ECC, filter) + includeEcc = True + + if (NVSMI_ALL in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DEV_MEM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_REGFILE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L1CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_L2CACHE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TEXTURE in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_SRAM in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_CBU in filter or + NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TOTAL in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_DEV_MEM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_REGFILE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_L1CACHE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_L2CACHE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_TEXTURE in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_DRAM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_SRAM in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_CBU in filter or + NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_TOTAL in filter ): + ecc['aggregate'] = nvidia_smi.__GetEccByCounter(handle, NVML_AGGREGATE_ECC, filter) + includeEcc = True + + return ecc if len(ecc.values()) > 0 else None, includeEcc + + @staticmethod + def __xmlGetRetiredPagesByCause(handle, cause): + retiredPagedByCause = '' + + error = None + count = 0 + try: + pages = nvmlDeviceGetRetiredPages(handle, cause) + count = sum(map(len, pages)) #[py2] count = nvidia_smi.__toString(len(pages)) + except NVMLError as err: + error = nvidia_smi.__handleError(err) + pages = None + + retiredPagedByCause += ' ' + nvidia_smi.__toString(count) + '\n' + if pages is not None: + retiredPagedByCause += ' \n' + for page in pages: + retiredPagedByCause += ' ' + "0x%016x" % page + '\n' + retiredPagedByCause += ' \n' + else: + retiredPagedByCause += ' ' + error + '\n' + + return retiredPagedByCause if count > 0 else '' + + @staticmethod + def __GetRetiredPagesByCause(handle, cause): + retiredPagedByCause = {} + + error = None + count = 0 + try: + pages = nvmlDeviceGetRetiredPages(handle, cause) + except NVMLError as err: + error = nvidia_smi.__handleError(err) + pages = None + + retiredPageAddresses = {} + if pages is not None: + ii = 1 + for page in pages: + retiredPageAddresses['retired_page_address_'+str(ii)] = "0x%016x" % page + ii+=1 + count+=1 + if error is not None: + retiredPageAddresses['Error'] = error + + retiredPagedByCause['retired_count'] = count + retiredPagedByCause['retired_page_addresses'] = retiredPageAddresses if len(retiredPageAddresses.values()) > 0 else None + + return retiredPagedByCause if count > 0 else None + + @staticmethod + def __xmlGetRetiredPages(handle, filter): + retiredPages = '' + includeRetiredPages = False + + causes = [ "multiple_single_bit_retirement", "double_bit_retirement" ] + for idx in range(NVML_PAGE_RETIREMENT_CAUSE_COUNT): + if (NVSMI_ALL in filter or + (NVSMI_RETIREDPAGES_SINGLE_BIT_ECC_COUNT in filter and idx == 0) or + (NVSMI_RETIREDPAGES_DOUBLE_BIT_ECC_COUNT in filter and idx == 1)): + retiredPages += ' <' + causes[idx] + '>\n' + retiredPages += nvidia_smi.__xmlGetRetiredPagesByCause(handle, idx) + retiredPages += ' \n' + includeRetiredPages = True + + if (NVSMI_ALL in filter or NVSMI_RETIREDPAGES_PENDING in filter): + retiredPages += ' ' + try: + if NVML_FEATURE_DISABLED == nvmlDeviceGetRetiredPagesPendingStatus(handle): + retiredPages += "No" + else: + retiredPages += "Yes" + except NVMLError as err: + retiredPages += nvidia_smi.__handleError(err) + retiredPages += '\n' + includeRetiredPages = True + + return retiredPages if len(retiredPages) > 0 else None, includeRetiredPages + + @staticmethod + def __GetRetiredPages(handle, filter): + retiredPages = {} + includeRetiredPages = False + + causes = [ "multiple_single_bit_retirement", "double_bit_retirement" ] + for idx in range(NVML_PAGE_RETIREMENT_CAUSE_COUNT): + if (NVSMI_ALL in filter or + (NVSMI_RETIREDPAGES_SINGLE_BIT_ECC_COUNT in filter and idx == 0) or + (NVSMI_RETIREDPAGES_DOUBLE_BIT_ECC_COUNT in filter and idx == 1)): + retiredPages[causes[idx]] = nvidia_smi.__GetRetiredPagesByCause(handle, idx) + includeRetiredPages = True + + if (NVSMI_ALL in filter or NVSMI_RETIREDPAGES_PENDING in filter): + pending_retirement = '' + try: + if NVML_FEATURE_DISABLED == nvmlDeviceGetRetiredPagesPendingStatus(handle): + pending_retirement = "No" + else: + pending_retirement = "Yes" + except NVMLError as err: + pending_retirement = nvidia_smi.__handleError(err) + retiredPages['pending_retirement'] = pending_retirement + includeRetiredPages = True + + return retiredPages if len(retiredPages.values()) > 0 else None, includeRetiredPages + + @staticmethod + def __toStrGOM(mode): + if mode == NVML_GOM_ALL_ON: + return "All On"; + elif mode == NVML_GOM_COMPUTE: + return "Compute"; + elif mode == NVML_GOM_LOW_DP: + return "Low Double Precision"; + else: + return "Unknown"; + + @staticmethod + def __xmlGetClocksThrottleReasons(handle): + throttleReasons = [ + [nvmlClocksThrottleReasonGpuIdle, "clocks_throttle_reason_gpu_idle"], + [nvmlClocksThrottleReasonUserDefinedClocks, "clocks_throttle_reason_user_defined_clocks"], + [nvmlClocksThrottleReasonApplicationsClocksSetting, "clocks_throttle_reason_applications_clocks_setting"], + [nvmlClocksThrottleReasonSwPowerCap, "clocks_throttle_reason_sw_power_cap"], + [nvmlClocksThrottleReasonHwSlowdown, "clocks_throttle_reason_hw_slowdown"], + [nvmlClocksThrottleReasonNone, "clocks_throttle_reason_none"] + ]; + + strResult = '' + + try: + supportedClocksThrottleReasons = nvmlDeviceGetSupportedClocksThrottleReasons(handle); + clocksThrottleReasons = nvmlDeviceGetCurrentClocksThrottleReasons(handle); + strResult += ' \n' + for (mask, name) in throttleReasons: + if (name != "clocks_throttle_reason_user_defined_clocks"): + if (mask & supportedClocksThrottleReasons): + val = "Active" if mask & clocksThrottleReasons else "Not Active"; + else: + val = "N/A" #nvidia_smi.__handleError(NVML_ERROR_NOT_SUPPORTED); + strResult += " <%s>%s\n" % (name, val, name); + strResult += ' \n' + except NVMLError as err: + strResult += ' %s\n' % (nvidia_smi.__handleError(err)); + + return strResult; + + @staticmethod + def __GetClocksThrottleReasons(handle): + throttleReasons = [ + [nvmlClocksThrottleReasonGpuIdle, "clocks_throttle_reason_gpu_idle"], + [nvmlClocksThrottleReasonUserDefinedClocks, "clocks_throttle_reason_user_defined_clocks"], + [nvmlClocksThrottleReasonApplicationsClocksSetting, "clocks_throttle_reason_applications_clocks_setting"], + [nvmlClocksThrottleReasonSwPowerCap, "clocks_throttle_reason_sw_power_cap"], + [nvmlClocksThrottleReasonHwSlowdown, "clocks_throttle_reason_hw_slowdown"], + [nvmlClocksThrottleReasonNone, "clocks_throttle_reason_none"] + ]; + + clockThrottleReasons = {} + + try: + supportedClocksThrottleReasons = nvmlDeviceGetSupportedClocksThrottleReasons(handle); + clocksThrottleReasons = nvmlDeviceGetCurrentClocksThrottleReasons(handle); + for (mask, name) in throttleReasons: + if (name != "clocks_throttle_reason_user_defined_clocks"): + if (mask & supportedClocksThrottleReasons): + val = "Active" if mask & clocksThrottleReasons else "Not Active"; + else: + val = "N/A" #nvidia_smi.__handleError(NVML_ERROR_NOT_SUPPORTED); + clockThrottleReasons[name]= val; + except NVMLError as err: + clockThrottleReasons['Error'] = nvidia_smi.__handleError(err); + + return clockThrottleReasons if len(clockThrottleReasons.values()) > 0 else None + + # + # Converts errors into string messages + # + @staticmethod + def __handleError(err): + if (err.value == NVML_ERROR_NOT_SUPPORTED): + return "N/A" + else: + return err.__str__() + + @staticmethod + def __toString(val): + if (isinstance(val, bytes)): + return val.decode("utf-8") + return str(val) + + + @classmethod + def XmlDeviceQuery(self, filter=None): + ''' + Provides a Python interface to GPU management and monitoring functions. + + This is a wrapper around the NVML library. + For information about the NVML library, see the NVML developer page + http://developer.nvidia.com/nvidia-management-library-nvml + + Examples: + --------------------------------------------------------------------------- + For all elements as in XML format. Similiar to nvisia-smi -q -x + + $ XmlDeviceQuery() + + --------------------------------------------------------------------------- + For XML of filtered elements by string name. + Similiar ot nvidia-smi --query-gpu=pci.bus_id,memory.total,memory.free + See help_query_gpu.txt or XmlDeviceQuery("--help-query-gpu") for available filter elements + + $ XmlDeviceQuery("pci.bus_id,memory.total,memory.free") + + --------------------------------------------------------------------------- + For XML of filtered elements by enumeration value. + See help_query_gpu.txt or XmlDeviceQuery("--help_query_gpu") for available filter elements + + $ XmlDeviceQuery([NVSMI_PCI_BUS_ID, NVSMI_MEMORY_TOTAL, NVSMI_MEMORY_FREE]) + + ''' + + if (filter is None): + filter = [NVSMI_ALL] + elif (isinstance(filter, str)): + if (filter == "--help") or (filter == "-h"): + return nvidia_smi.XmlDeviceQuery.__doc__ + elif (filter == "--help-query-gpu"): + with open("help_query_gpu.txt", 'r') as fin: + return fin.read() + else: + filter = nvidia_smi.__fromDeviceQueryString(filter) + else: + filter = list(filter) + + strResult = '' + try: + strResult += '\n' + strResult += '\n' + strResult += '\n' + + if (NVSMI_ALL in filter or NVSMI_TIMESTAMP in filter): + strResult += ' ' + nvidia_smi.__toString(datetime.date.today()) + '\n' + if (NVSMI_ALL in filter or NVSMI_DRIVER_VERSION in filter): + strResult += ' ' + nvidia_smi.__toString(nvmlSystemGetDriverVersion()) + '\n' + + deviceCount = nvmlDeviceGetCount() + if (NVSMI_ALL in filter or NVSMI_COUNT in filter): + strResult += ' ' + nvidia_smi.__toString(deviceCount) + '\n' + + for i in range(0, deviceCount): + handle = self.__handles[i] + + pciInfo = nvmlDeviceGetPciInfo(handle) + + gpuInfo = '' + + if (NVSMI_ALL in filter or NVSMI_PCI_BUS_ID in filter): + gpuInfo += ' %s\n' % pciInfo.busId + + if (NVSMI_ALL in filter or NVSMI_NAME in filter): + gpuInfo += ' ' + nvidia_smi.__toString(nvmlDeviceGetName(handle)) + '\n' + + try: + # if nvmlDeviceGetBrand() succeeds it is guaranteed to be in the dictionary + brandName = NVSMI_BRAND_NAMES[nvmlDeviceGetBrand(handle)] + except NVMLError as err: + brandName = nvidia_smi.__handleError(err) + + + gpuInfo += ' ' + brandName + '\n' + + if (NVSMI_ALL in filter or NVSMI_DISPLAY_MODE in filter): + try: + state = ('Enabled' if (nvmlDeviceGetDisplayMode(handle) != 0) else 'Disabled') + except NVMLError as err: + state = nvidia_smi.__handleError(err) + + gpuInfo += ' ' + state + '\n' + + if (NVSMI_ALL in filter or NVSMI_DISPLAY_ACTIVE in filter): + try: + state = ('Enabled' if (nvmlDeviceGetDisplayActive(handle) != 0) else 'Disabled') + except NVMLError as err: + state = nvidia_smi.__handleError(err) + + gpuInfo += ' ' + state + '\n' + + if (NVSMI_ALL in filter or NVSMI_PERSISTENCE_MODE in filter): + try: + mode = 'Enabled' if (nvmlDeviceGetPersistenceMode(handle) != 0) else 'Disabled' + except NVMLError as err: + mode = nvidia_smi.__handleError(err) + + gpuInfo += ' ' + mode + '\n' + + if (NVSMI_ALL in filter or NVSMI_ACCT_MODE in filter): + try: + mode = 'Enabled' if (nvmlDeviceGetAccountingMode(handle) != 0) else 'Disabled' + except NVMLError as err: + mode = nvidia_smi.__handleError(err) + + gpuInfo += ' ' + mode + '\n' + + if (NVSMI_ALL in filter or NVSMI_ACCT_BUFFER_SIZE in filter): + try: + bufferSize = nvidia_smi.__toString(nvmlDeviceGetAccountingBufferSize(handle)) + except NVMLError as err: + bufferSize = nvidia_smi.__handleError(err) + + gpuInfo += ' ' + bufferSize + '\n' + + migMode = '' + includeMigMode = False + if (NVSMI_ALL in filter or + NVSMI_MIG_MODE_CURRENT in filter or + NVSMI_MIG_MODE_PENDING in filter): + try: + (current, pending) = nvmlDeviceGetMigMode(handle) + current = 'Enabled' if current == NVML_DEVICE_MIG_ENABLE else 'Disabled' + pending = 'Enabled' if pending == NVML_DEVICE_MIG_ENABLE else 'Disabled' + except NVMLError as err: + current = nvidia_smi.__handleError(err) + pending = current + migMode += ' ' + current + '\n' + migMode += ' ' + pending + '\n' + includeMigMode = True + + if includeMigMode: + gpuInfo += ' \n' + gpuInfo += migMode + gpuInfo += ' \n' + + driverModel = '' + includeDriverModel = False + + if (NVSMI_ALL in filter or NVSMI_DRIVER_MODEL_CUR in filter): + try: + current = 'WDDM' if (nvmlDeviceGetCurrentDriverModel(handle) == NVML_DRIVER_WDDM) else 'TCC' + except NVMLError as err: + current = nvidia_smi.__handleError(err) + driverModel += ' ' + current + '\n' + includeDriverModel = True + + if (NVSMI_ALL in filter or NVSMI_DRIVER_MODEL_PENDING in filter): + try: + pending = 'WDDM' if (nvmlDeviceGetPendingDriverModel(handle) == NVML_DRIVER_WDDM) else 'TCC' + except NVMLError as err: + pending = nvidia_smi.__handleError(err) + driverModel += ' ' + pending + '\n' + includeDriverModel = True + + if includeDriverModel: + gpuInfo += ' \n' + gpuInfo += driverModel + gpuInfo += ' \n' + + if (NVSMI_ALL in filter or NVSMI_SERIALNUMBER in filter): + try: + serial = nvmlDeviceGetSerial(handle) + except NVMLError as err: + serial = nvidia_smi.__handleError(err) + + gpuInfo += ' ' + nvidia_smi.__toString(serial) + '\n' + + if (NVSMI_ALL in filter or NVSMI_UUID in filter): + try: + uuid = nvmlDeviceGetUUID(handle) + except NVMLError as err: + uuid = nvidia_smi.__handleError(err) + + gpuInfo += ' ' + nvidia_smi.__toString(uuid) + '\n' + + if (NVSMI_ALL in filter or NVSMI_INDEX in filter): + try: + minor_number = nvmlDeviceGetMinorNumber(handle) + except NVMLError as err: + minor_number = nvidia_smi.__handleError(err) + + gpuInfo += ' ' + nvidia_smi.__toString(minor_number) + '\n' + + if (NVSMI_ALL in filter or NVSMI_VBIOS_VER in filter): + try: + vbios = nvmlDeviceGetVbiosVersion(handle) + except NVMLError as err: + vbios = nvidia_smi.__handleError(err) + + gpuInfo += ' ' + nvidia_smi.__toString(vbios) + '\n' + + if (NVSMI_ALL in filter or NVSMI_VBIOS_VER in filter): + try: + multiGpuBool = nvmlDeviceGetMultiGpuBoard(handle) + except NVMLError as err: + multiGpuBool = nvidia_smi.__handleError(err); + + if multiGpuBool == "N/A": + gpuInfo += ' ' + 'N/A' + '\n' + elif multiGpuBool: + gpuInfo += ' ' + 'Yes' + '\n' + else: + gpuInfo += ' ' + 'No' + '\n' + + if (NVSMI_ALL in filter or NVSMI_BOARD_ID in filter): + try: + boardId = nvmlDeviceGetBoardId(handle) + except NVMLError as err: + boardId = nvidia_smi.__handleError(err) + + try: + hexBID = "0x%x" % boardId + except: + hexBID = boardId + + gpuInfo += ' ' + hexBID + '\n' + + inforomVersion = '' + includeInforom = False + if (NVSMI_ALL in filter or NVSMI_INFOROM_IMG in filter): + try: + img = nvmlDeviceGetInforomImageVersion(handle) + except NVMLError as err: + img = nvidia_smi.__handleError(err) + + inforomVersion += ' ' + nvidia_smi.__toString(img) + '\n' + includeInforom = True + + if (NVSMI_ALL in filter or NVSMI_INFOROM_OEM in filter): + try: + oem = nvmlDeviceGetInforomVersion(handle, NVML_INFOROM_OEM) + except NVMLError as err: + oem = nvidia_smi.__handleError(err) + + inforomVersion += ' ' + nvidia_smi.__toString(oem) + '\n' + includeInforom = True + + if (NVSMI_ALL in filter or NVSMI_INFOROM_ECC in filter): + try: + ecc = nvmlDeviceGetInforomVersion(handle, NVML_INFOROM_ECC) + except NVMLError as err: + ecc = nvidia_smi.__handleError(err) + + inforomVersion += ' ' + nvidia_smi.__toString(ecc) + '\n' + includeInforom = True + + if (NVSMI_ALL in filter or NVSMI_INFOROM_PWR in filter): + try: + pwr = nvmlDeviceGetInforomVersion(handle, NVML_INFOROM_POWER) + except NVMLError as err: + pwr = nvidia_smi.__handleError(err) + + inforomVersion += ' ' + nvidia_smi.__toString(pwr) + '\n' + includeInforom = True + + if includeInforom: + gpuInfo += ' \n' + gpuInfo += inforomVersion + gpuInfo += ' \n' + + gpuOperationMode = '' + includeGOM = False + if (NVSMI_ALL in filter or NVSMI_GOM_CUR in filter): + try: + current = nvidia_smi.__toStrGOM(nvmlDeviceGetCurrentGpuOperationMode(handle)) + except NVMLError as err: + current = nvidia_smi.__handleError(err) + gpuOperationMode += ' ' + nvidia_smi.__toString(current) + '\n' + includeGOM = True + + if (NVSMI_ALL in filter or NVSMI_GOM_PENDING in filter): + try: + pending = nvidia_smi.__toStrGOM(nvmlDeviceGetPendingGpuOperationMode(handle)) + except NVMLError as err: + pending = nvidia_smi.__handleError(err) + + gpuOperationMode += ' ' + nvidia_smi.__toString(pending) + '\n' + includeGOM = True + + if includeGOM: + gpuInfo += ' \n' + gpuInfo += gpuOperationMode + gpuInfo += ' \n' + + pci = '' + includePci = False + + if (NVSMI_ALL in filter or NVSMI_PCI_BUS in filter): + pci += ' %02X\n' % pciInfo.bus + includePci = True + + if (NVSMI_ALL in filter or NVSMI_PCI_DEVICE in filter): + pci += ' %02X\n' % pciInfo.device + includePci = True + + if (NVSMI_ALL in filter or NVSMI_PCI_DOMAIN in filter): + pci += ' %04X\n' % pciInfo.domain + includePci = True + + if (NVSMI_ALL in filter or NVSMI_PCI_DEVICE_ID in filter): + pci += ' %08X\n' % (pciInfo.pciDeviceId) + includePci = True + + if (NVSMI_ALL in filter or NVSMI_PCI_BUS_ID in filter): + pci += ' ' + nvidia_smi.__toString(pciInfo.busId) + '\n' + includePci = True + + if (NVSMI_ALL in filter or NVSMI_PCI_SUBDEVICE_ID in filter): + pci += ' %08X\n' % (pciInfo.pciSubSystemId) + includePci = True + + pciGpuLinkInfo = '' + includeLinkInfo = False + pciGen = '' + includeGen = False + + if (NVSMI_ALL in filter or NVSMI_PCI_LINK_GEN_MAX in filter): + try: + gen = nvidia_smi.__toString(nvmlDeviceGetMaxPcieLinkGeneration(handle)) + except NVMLError as err: + gen = nvidia_smi.__handleError(err) + + pciGen += ' ' + gen + '\n' + includeGen = True + + if (NVSMI_ALL in filter or NVSMI_PCI_LINK_GEN_CUR in filter): + try: + gen = nvidia_smi.__toString(nvmlDeviceGetCurrPcieLinkGeneration(handle)) + except NVMLError as err: + gen = nvidia_smi.__handleError(err) + + pciGen += ' ' + gen + '\n' + includeGen = True + + if includeGen: + pciGpuLinkInfo += ' \n' + pciGpuLinkInfo += pciGen + pciGpuLinkInfo += ' \n' + includeLinkInfo = True + + pciLinkWidths = '' + includeLinkWidths = False + + if (NVSMI_ALL in filter or NVSMI_PCI_LINK_WIDTH_MAX in filter): + try: + width = nvidia_smi.__toString(nvmlDeviceGetMaxPcieLinkWidth(handle)) + 'x' + except NVMLError as err: + width = nvidia_smi.__handleError(err) + + pciLinkWidths += ' ' + width + '\n' + includeLinkWidths = True + + if (NVSMI_ALL in filter or NVSMI_PCI_LINK_WIDTH_CUR in filter): + try: + width = nvidia_smi.__toString(nvmlDeviceGetCurrPcieLinkWidth(handle)) + 'x' + except NVMLError as err: + width = nvidia_smi.__handleError(err) + + pciLinkWidths += ' ' + width + '\n' + includeLinkWidths = True + + if includeLinkWidths: + pciGpuLinkInfo += ' \n' + pciGpuLinkInfo += pciLinkWidths + pciGpuLinkInfo += ' \n' + includeLinkInfo = True + + if includeLinkInfo: + pci += ' \n' + pci += pciGpuLinkInfo + pci += ' \n' + + + pciBridgeChip = '' + includeBridgeChip = False + + if (NVSMI_ALL in filter): + try: + bridgeHierarchy = nvmlDeviceGetBridgeChipInfo(handle) + bridge_type = '' + if bridgeHierarchy.bridgeChipInfo[0].type == 0: + bridge_type += 'PLX' + else: + bridge_type += 'BR04' + pciBridgeChip += ' ' + bridge_type + '\n' + + if bridgeHierarchy.bridgeChipInfo[0].fwVersion == 0: + strFwVersion = 'N/A' + else: + strFwVersion = '%08X' % (bridgeHierarchy.bridgeChipInfo[0].fwVersion) + pciBridgeChip += ' %s\n' % (strFwVersion) + except NVMLError as err: + pciBridgeChip += ' ' + nvidia_smi.__handleError(err) + '\n' + pciBridgeChip += ' ' + nvidia_smi.__handleError(err) + '\n' + includeBridgeChip = True + + if includeBridgeChip: + # Add additional code for hierarchy of bridges for Bug # 1382323 + pci += ' \n' + pci += pciBridgeChip + pci += ' \n' + + if (NVSMI_ALL in filter): + try: + replay = nvmlDeviceGetPcieReplayCounter(handle) + pci += ' ' + nvidia_smi.__toString(replay) + '' + except NVMLError as err: + pci += ' ' + nvidia_smi.__handleError(err) + '' + includePci = True + + if (NVSMI_ALL in filter): + try: + tx_bytes = nvmlDeviceGetPcieThroughput(handle, NVML_PCIE_UTIL_TX_BYTES) + pci += ' ' + nvidia_smi.__toString(tx_bytes) + ' KB/s' + '' + except NVMLError as err: + pci += ' ' + nvidia_smi.__handleError(err) + '' + includePci = True + + if (NVSMI_ALL in filter): + try: + rx_bytes = nvmlDeviceGetPcieThroughput(handle, NVML_PCIE_UTIL_RX_BYTES) + pci += ' ' + nvidia_smi.__toString(rx_bytes) + ' KB/s' + '' + except NVMLError as err: + pci += ' ' + nvidia_smi.__handleError(err) + '' + includePci = True + + if includePci: + gpuInfo += ' \n' + gpuInfo += pci + gpuInfo += ' \n' + + if (NVSMI_ALL in filter or NVSMI_FAN_SPEED in filter): + try: + fan = nvidia_smi.__toString(nvmlDeviceGetFanSpeed(handle)) + ' %' + except NVMLError as err: + fan = nvidia_smi.__handleError(err) + gpuInfo += ' ' + fan + '\n' + + if (NVSMI_ALL in filter or NVSMI_PSTATE in filter): + try: + perfState = nvmlDeviceGetPowerState(handle) + perfStateStr = 'P%s' % perfState + except NVMLError as err: + perfStateStr = nvidia_smi.__handleError(err) + gpuInfo += ' ' + perfStateStr + '\n' + + if (NVSMI_ALL in filter or + NVSMI_CLOCK_THROTTLE_REASONS_SUPPORTED in filter or + NVSMI_CLOCK_THROTTLE_REASONS_ACTIVE in filter or + NVSMI_CLOCK_THROTTLE_REASONS_IDLE in filter or + NVSMI_CLOCK_THROTTLE_REASONS_APP_SETTING in filter or + NVSMI_CLOCK_THROTTLE_REASONS_SW_PWR_CAP in filter or + NVSMI_CLOCK_THROTTLE_REASONS_HW_SLOWDOWN in filter or + NVSMI_CLOCK_THROTTLE_REASONS_HW_THERMAL_SLOWDOWN in filter or + NVSMI_CLOCK_THROTTLE_REASONS_HW_PWR_BRAKE_SLOWDOWN in filter or + NVSMI_CLOCK_THROTTLE_REASONS_SW_THERMAL_SLOWDOWN in filter or + NVSMI_CLOCK_THROTTLE_REASONS_SYNC_BOOST in filter): + gpuInfo += nvidia_smi.__xmlGetClocksThrottleReasons(handle); + + fbMemoryUsage = '' + includeMemoryUsage = False + if (NVSMI_ALL in filter or + NVSMI_MEMORY_TOTAL in filter or + NVSMI_MEMORY_USED in filter or + NVSMI_MEMORY_FREE in filter): + + includeMemoryUsage = True + try: + memInfo = nvmlDeviceGetMemoryInfo(handle) + mem_total = nvidia_smi.__toString(memInfo.total / 1024 / 1024) + ' MiB' + mem_used = nvidia_smi.__toString(memInfo.used / 1024 / 1024) + ' MiB' + mem_free = nvidia_smi.__toString(memInfo.total / 1024 / 1024 - memInfo.used / 1024 / 1024) + ' MiB' + except NVMLError as err: + error = nvidia_smi.__handleError(err) + mem_total = error + mem_used = error + mem_free = error + + if (NVSMI_ALL in filter or NVSMI_MEMORY_TOTAL in filter): + fbMemoryUsage += ' ' + mem_total + '\n' + if (NVSMI_ALL in filter or NVSMI_MEMORY_USED in filter): + fbMemoryUsage += ' ' + mem_used + '\n' + if (NVSMI_ALL in filter or NVSMI_MEMORY_FREE in filter): + fbMemoryUsage += ' ' + mem_free + '\n' + + if includeMemoryUsage: + gpuInfo += ' \n' + gpuInfo += fbMemoryUsage + gpuInfo += ' \n' + + if (NVSMI_ALL in filter or NVSMI_MEMORY_BAR1 in filter): + try: + memInfo = nvmlDeviceGetBAR1MemoryInfo(handle) + mem_total = nvidia_smi.__toString(memInfo.bar1Total / 1024 / 1024) + ' MiB' + mem_used = nvidia_smi.__toString(memInfo.bar1Used / 1024 / 1024) + ' MiB' + mem_free = nvidia_smi.__toString(memInfo.bar1Total / 1024 / 1024 - memInfo.bar1Used / 1024 / 1024) + ' MiB' + except NVMLError as err: + error = nvidia_smi.__handleError(err) + mem_total = error + mem_used = error + mem_free = error + + gpuInfo += ' \n' + gpuInfo += ' ' + mem_total + '\n' + gpuInfo += ' ' + mem_used + '\n' + gpuInfo += ' ' + mem_free + '\n' + gpuInfo += ' \n' + + if (NVSMI_ALL in filter or NVSMI_COMPUTE_MODE in filter): + try: + mode = nvmlDeviceGetComputeMode(handle) + if mode == NVML_COMPUTEMODE_DEFAULT: + modeStr = 'Default' + elif mode == NVML_COMPUTEMODE_EXCLUSIVE_THREAD: + modeStr = 'Exclusive Thread' + elif mode == NVML_COMPUTEMODE_PROHIBITED: + modeStr = 'Prohibited' + elif mode == NVML_COMPUTEMODE_EXCLUSIVE_PROCESS: + modeStr = 'Exclusive_Process' + else: + modeStr = 'Unknown' + except NVMLError as err: + modeStr = nvidia_smi.__handleError(err) + + gpuInfo += ' ' + modeStr + '\n' + + utilization = '' + includeUtilization = False + if (NVSMI_ALL in filter or + NVSMI_UTILIZATION_GPU in filter or + NVSMI_UTILIZATION_MEM in filter): + try: + util = nvmlDeviceGetUtilizationRates(handle) + gpu_util = nvidia_smi.__toString(util.gpu) + ' %' + mem_util = nvidia_smi.__toString(util.memory) + ' %' + except NVMLError as err: + error = nvidia_smi.__handleError(err) + gpu_util = error + mem_util = error + + if (NVSMI_ALL in filter or NVSMI_UTILIZATION_GPU in filter): + utilization += ' ' + gpu_util + '\n' + + if (NVSMI_ALL in filter or NVSMI_UTILIZATION_MEM in filter): + utilization += ' ' + mem_util + '\n' + + includeUtilization = True + + if (NVSMI_ALL in filter or NVSMI_UTILIZATION_ENCODER in filter): + try: + (util_int, ssize) = nvmlDeviceGetEncoderUtilization(handle) + encoder_util = nvidia_smi.__toString(util_int) + ' %' + except NVMLError as err: + error = nvidia_smi.__handleError(err) + encoder_util = error + + utilization += ' ' + encoder_util + '\n' + + includeUtilization = True + + if (NVSMI_ALL in filter or NVSMI_UTILIZATION_DECODER in filter): + try: + (util_int, ssize) = nvmlDeviceGetDecoderUtilization(handle) + decoder_util = nvidia_smi.__toString(util_int) + ' %' + except NVMLError as err: + error = nvidia_smi.__handleError(err) + decoder_util = error + + utilization += ' ' + decoder_util + '\n' + + includeUtilization = True + + if includeUtilization: + gpuInfo += ' \n' + gpuInfo += utilization + gpuInfo += ' \n' + + if (NVSMI_ALL in filter or + NVSMI_ECC_MODE_CUR in filter or + NVSMI_ECC_MODE_PENDING in filter): + try: + (current, pending) = nvmlDeviceGetEccMode(handle) + curr_str = 'Enabled' if (current != 0) else 'Disabled' + pend_str = 'Enabled' if (pending != 0) else 'Disabled' + except NVMLError as err: + error = nvidia_smi.__handleError(err) + curr_str = error + pend_str = error + + eccMode = '' + if (NVSMI_ALL in filter or NVSMI_ECC_MODE_CUR in filter): + eccMode += ' ' + curr_str + '\n' + if (NVSMI_ALL in filter or NVSMI_ECC_MODE_PENDING in filter): + eccMode += ' ' + pend_str + '\n' + + gpuInfo += ' \n' + gpuInfo += eccMode + gpuInfo += ' \n' + + eccErrors,includeEccErrors = nvidia_smi.__xmlGetEcc(handle, filter) + if includeEccErrors: + gpuInfo += ' \n' + gpuInfo += eccErrors + gpuInfo += ' \n' + + retiredPages, includeRetiredPages = nvidia_smi.__xmlGetRetiredPages(handle, filter) + if includeRetiredPages: + gpuInfo += ' \n' + gpuInfo += retiredPages + gpuInfo += ' \n' + + temperature = '' + includeTemperature = False + + if (NVSMI_ALL in filter or NVSMI_TEMPERATURE_GPU in filter): + try: + temp = nvidia_smi.__toString(nvmlDeviceGetTemperature(handle, NVML_TEMPERATURE_GPU)) + ' C' + except NVMLError as err: + temp = nvidia_smi.__handleError(err) + + temperature += ' ' + temp + '\n' + + try: + temp = nvidia_smi.__toString(nvmlDeviceGetTemperatureThreshold(handle, NVML_TEMPERATURE_THRESHOLD_SHUTDOWN)) + ' C' + except NVMLError as err: + temp = nvidia_smi.__handleError(err) + + temperature += ' ' + temp + '\n' + includeTemperature = True + + try: + temp = nvidia_smi.__toString(nvmlDeviceGetTemperatureThreshold(handle, NVML_TEMPERATURE_THRESHOLD_SLOWDOWN)) + ' C' + except NVMLError as err: + temp = nvidia_smi.__handleError(err) + + temperature += ' ' + temp + '\n' + includeTemperature = True + + if includeTemperature: + gpuInfo += ' \n' + gpuInfo + temperature + gpuInfo += ' \n' + + power_readings = '' + includePowerReadings = False + + if (NVSMI_ALL in filter or NVSMI_POWER_MGMT in filter): + try: + powMan = nvmlDeviceGetPowerManagementMode(handle) + powManStr = 'Supported' if powMan != 0 else 'N/A' + except NVMLError as err: + powManStr = nvidia_smi.__handleError(err) + power_readings += ' ' + powManStr + '\n' + includePowerReadings = True + + if (NVSMI_ALL in filter or NVSMI_POWER_DRAW in filter): + try: + powDraw = (nvmlDeviceGetPowerUsage(handle) / 1000.0) + powDrawStr = '%.2f W' % powDraw + except NVMLError as err: + powDrawStr = nvidia_smi.__handleError(err) + power_readings += ' ' + powDrawStr + '\n' + includePowerReadings = True + + if (NVSMI_ALL in filter or NVSMI_POWER_LIMIT in filter): + try: + powLimit = (nvmlDeviceGetPowerManagementLimit(handle) / 1000.0) + powLimitStr = '%.2f W' % powLimit + except NVMLError as err: + powLimitStr = nvidia_smi.__handleError(err) + power_readings += ' ' + powLimitStr + '\n' + includePowerReadings = True + + if (NVSMI_ALL in filter or NVSMI_POWER_LIMIT_DEFAULT in filter): + try: + powLimit = (nvmlDeviceGetPowerManagementDefaultLimit(handle) / 1000.0) + powLimitStr = '%.2f W' % powLimit + except NVMLError as err: + powLimitStr = nvidia_smi.__handleError(err) + power_readings += ' ' + powLimitStr + '\n' + includePowerReadings = True + + if (NVSMI_ALL in filter or NVSMI_POWER_LIMIT_ENFORCED in filter): + try: + enforcedPowLimit = (nvmlDeviceGetEnforcedPowerLimit(handle) / 1000.0) + enforcedPowLimitStr = '%.2f W' % enforcedPowLimit + except NVMLError as err: + enforcedPowLimitStr = nvidia_smi.__handleError(err) + power_readings += ' ' + enforcedPowLimitStr + '\n' + includePowerReadings = True + + if (NVSMI_ALL in filter or + NVSMI_POWER_LIMIT_MIN in filter or + NVSMI_POWER_LIMIT_MAX in filter): + try: + powLimit = nvmlDeviceGetPowerManagementLimitConstraints(handle) + powLimitStrMin = '%.2f W' % (powLimit[0] / 1000.0) + powLimitStrMax = '%.2f W' % (powLimit[1] / 1000.0) + except NVMLError as err: + error = nvidia_smi.__handleError(err) + powLimitStrMin = error + powLimitStrMax = error + if (NVSMI_ALL in filter or NVSMI_POWER_LIMIT_MIN in filter): + power_readings += ' ' + powLimitStrMin + '\n' + if (NVSMI_ALL in filter or NVSMI_POWER_LIMIT_MAX in filter): + power_readings += ' ' + powLimitStrMax + '\n' + includePowerReadings = True + + if includePowerReadings: + gpuInfo += ' \n' + try: + perfState = 'P' + nvidia_smi.__toString(nvmlDeviceGetPowerState(handle)) + except NVMLError as err: + perfState = nvidia_smi.__handleError(err) + gpuInfo += ' %s\n' % perfState + gpuInfo += power_readings + gpuInfo += ' \n' + + clocks = '' + includeClocks = False + if(NVSMI_ALL in filter or NVSMI_CLOCKS_GRAPHICS_CUR in filter): + try: + graphics = nvidia_smi.__toString(nvmlDeviceGetClockInfo(handle, NVML_CLOCK_GRAPHICS)) + ' MHz' + except NVMLError as err: + graphics = nvidia_smi.__handleError(err) + clocks += ' ' +graphics + '\n' + includeClocks = True; + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_GRAPHICS_CUR in filter): + try: + sm = nvidia_smi.__toString(nvmlDeviceGetClockInfo(handle, NVML_CLOCK_SM)) + ' MHz' + except NVMLError as err: + sm = nvidia_smi.__handleError(err) + clocks += ' ' + sm + '\n' + includeClocks = True; + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_MEMORY_CUR in filter): + try: + mem = nvidia_smi.__toString(nvmlDeviceGetClockInfo(handle, NVML_CLOCK_MEM)) + ' MHz' + except NVMLError as err: + mem = nvidia_smi.__handleError(err) + clocks += ' ' + mem + '\n' + includeClocks = True; + + if includeClocks: + gpuInfo += ' \n' + gpuInfo += clocks + gpuInfo += ' \n' + + applicationClocks = '' + includeAppClocks = False + if(NVSMI_ALL in filter or NVSMI_CLOCKS_APPL_GRAPHICS in filter): + try: + graphics = nvidia_smi.__toString(nvmlDeviceGetApplicationsClock(handle, NVML_CLOCK_GRAPHICS)) + ' MHz' + except NVMLError as err: + graphics = nvidia_smi.__handleError(err) + applicationClocks += ' ' +graphics + '\n' + includeAppClocks = True + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_APPL_MEMORY in filter): + try: + mem = nvidia_smi.__toString(nvmlDeviceGetApplicationsClock(handle, NVML_CLOCK_MEM)) + ' MHz' + except NVMLError as err: + mem = nvidia_smi.__handleError(err) + applicationClocks += ' ' + mem + '\n' + includeAppClocks = True + + if includeAppClocks: + gpuInfo += ' \n' + gpuInfo += applicationClocks + gpuInfo += ' \n' + + defaultApplicationClocks = '' + includeDefaultAppClocks = False + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_APPL_GRAPHICS_DEFAULT in filter): + try: + graphics = nvidia_smi.__toString(nvmlDeviceGetDefaultApplicationsClock(handle, NVML_CLOCK_GRAPHICS)) + ' MHz' + except NVMLError as err: + graphics = nvidia_smi.__handleError(err) + defaultApplicationClocks += ' ' +graphics + '\n' + includeDefaultAppClocks = True + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_APPL_MEMORY_DEFAULT in filter): + try: + mem = nvidia_smi.__toString(nvmlDeviceGetDefaultApplicationsClock(handle, NVML_CLOCK_MEM)) + ' MHz' + except NVMLError as err: + mem = nvidia_smi.__handleError(err) + defaultApplicationClocks += ' ' + mem + '\n' + includeDefaultAppClocks = True + + if includeDefaultAppClocks: + gpuInfo += ' \n' + gpuInfo += defaultApplicationClocks + gpuInfo += ' \n' + + maxClocks = '' + includeMaxClocks = False + if(NVSMI_ALL in filter or NVSMI_CLOCKS_GRAPHICS_MAX in filter): + try: + graphics = nvidia_smi.__toString(nvmlDeviceGetMaxClockInfo(handle, NVML_CLOCK_GRAPHICS)) + ' MHz' + except NVMLError as err: + graphics = nvidia_smi.__handleError(err) + maxClocks += ' ' + graphics + '\n' + includeMaxClocks = True + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_SM_MAX in filter): + try: + sm = nvidia_smi.__toString(nvmlDeviceGetMaxClockInfo(handle, NVML_CLOCK_SM)) + ' MHz' + except NVMLError as err: + sm = nvidia_smi.__handleError(err) + maxClocks += ' ' + sm + '\n' + includeMaxClocks = True + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_MEMORY_MAX in filter): + try: + mem = nvidia_smi.__toString(nvmlDeviceGetMaxClockInfo(handle, NVML_CLOCK_MEM)) + ' MHz' + except NVMLError as err: + mem = nvidia_smi.__handleError(err) + maxClocks += ' ' + mem + '\n' + includeMaxClocks = True + + if includeMaxClocks: + gpuInfo += ' \n' + gpuInfo += maxClocks + gpuInfo += ' \n' + + if (NVSMI_ALL in filter or NVSMI_CLOCKS_POLICY in filter): + gpuInfo += ' \n' + try: + boostedState, boostedDefaultState = nvmlDeviceGetAutoBoostedClocksEnabled(handle) + if boostedState == NVML_FEATURE_DISABLED: + autoBoostStr = "Off" + else: + autoBoostStr = "On" + + if boostedDefaultState == NVML_FEATURE_DISABLED: + autoBoostDefaultStr = "Off" + else: + autoBoostDefaultStr = "On" + + except NVMLError_NotSupported: + autoBoostStr = "N/A" + autoBoostDefaultStr = "N/A" + except NVMLError as err: + autoBoostStr = nvidia_smi.__handleError(err) + autoBoostDefaultStr = nvidia_smi.__handleError(err) + pass + gpuInfo += ' ' + autoBoostStr + '\n' + gpuInfo += ' ' + autoBoostDefaultStr + '\n' + gpuInfo += ' \n' + + if (NVSMI_ALL in filter or NVSMI_CLOCKS_SUPPORTED in filter): + try: + memClocks = nvmlDeviceGetSupportedMemoryClocks(handle) + gpuInfo += ' \n' + + for m in memClocks: + gpuInfo += ' \n' + gpuInfo += ' %d MHz\n' % m + try: + clocks = nvmlDeviceGetSupportedGraphicsClocks(handle, m) + for c in clocks: + gpuInfo += ' %d MHz\n' % c + except NVMLError as err: + gpuInfo += ' %s\n' % nvidia_smi.__handleError(err) + gpuInfo += ' \n' + + gpuInfo += ' \n' + except NVMLError as err: + gpuInfo += ' ' + nvidia_smi.__handleError(err) + '\n' + + if (NVSMI_ALL in filter or NVSMI_COMPUTE_APPS in filter): + try: + procs = nvmlDeviceGetComputeRunningProcesses(handle) + gpuInfo += ' \n' + + for p in procs: + try: + name = nvidia_smi.__toString(nvmlSystemGetProcessName(p.pid)) + except NVMLError as err: + if (err.value == NVML_ERROR_NOT_FOUND): + # probably went away + continue + else: + name = nvidia_smi.__handleError(err) + + gpuInfo += ' \n' + gpuInfo += ' %d\n' % p.pid + gpuInfo += ' ' + name + '\n' + + if (p.usedGpuMemory == None): + mem = 'N/A' + else: + mem = '%d MiB' % (p.usedGpuMemory / 1024 / 1024) + gpuInfo += ' ' + mem + '\n' + gpuInfo += ' \n' + + gpuInfo += ' \n' + except NVMLError as err: + gpuInfo += ' ' + nvidia_smi.__handleError(err) + '\n' + + if (NVSMI_ALL in filter or NVSMI_ACCOUNTED_APPS in filter): + try: + pids = nvmlDeviceGetAccountingPids(handle) + gpuInfo += ' \n' + + for pid in pids : + try: + stats = nvmlDeviceGetAccountingStats(handle, pid) + gpuUtilization = "%d %%" % stats.gpuUtilization + memoryUtilization = "%d %%" % stats.memoryUtilization + if (stats.maxMemoryUsage == None): + maxMemoryUsage = 'N/A' + else: + maxMemoryUsage = '%d MiB' % (stats.maxMemoryUsage / 1024 / 1024) + time = "%d ms" % stats.time + is_running = "%d" % stats.isRunning + except NVMLError as err: + if (err.value == NVML_ERROR_NOT_FOUND): + # probably went away + continue + err = nvidia_smi.__handleError(err) + gpuUtilization = err + memoryUtilization = err + maxMemoryUsage = err + time = err + is_running = err + + gpuInfo += ' \n' + gpuInfo += ' %d\n' % pid + gpuInfo += ' ' + gpuUtilization + '\n' + gpuInfo += ' ' + memoryUtilization + '\n' + gpuInfo += ' ' + maxMemoryUsage+ '\n' + gpuInfo += ' \n' + gpuInfo += ' ' + is_running + '\n' + gpuInfo += ' \n' + + gpuInfo += ' \n' + except NVMLError as err: + gpuInfo += ' ' + nvidia_smi.__handleError(err) + '\n' + + if len(gpuInfo) >0: + strResult += ' ' + strResult += gpuInfo + strResult += ' \n' + + strResult += '\n' + + except NVMLError as err: + strResult += 'nvidia_smi.py: ' + err.__str__() + '\n' + + return strResult + + @classmethod + def DeviceQuery(self, filter=None): + ''' + Provides a Python interface to GPU management and monitoring functions. + + This is a wrapper around the NVML library. + For information about the NVML library, see the NVML developer page + http://developer.nvidia.com/nvidia-management-library-nvml + + Examples: + --------------------------------------------------------------------------- + For all elements as a list of dictionaries. Similiar to nvisia-smi -q -x + + $ DeviceQuery() + + --------------------------------------------------------------------------- + For a list of filtered dictionary elements by string name. + Similiar ot nvidia-smi --query-gpu=pci.bus_id,memory.total,memory.free + See help_query_gpu.txt or DeviceQuery("--help_query_gpu") for available filter elements + + $ DeviceQuery("pci.bus_id,memory.total,memory.free") + + --------------------------------------------------------------------------- + For a list of filtered dictionary elements by enumeration value. + See help_query_gpu.txt or DeviceQuery("--help-query-gpu") for available filter elements + + $ DeviceQuery([NVSMI_PCI_BUS_ID, NVSMI_MEMORY_TOTAL, NVSMI_MEMORY_FREE]) + + ''' + + if (filter is None): + filter = [NVSMI_ALL] + elif (isinstance(filter, str)): + if (filter == "--help") or (filter == "-h"): + return nvidia_smi.DeviceQuery.__doc__ + elif (filter == "--help-query-gpu"): + with open("help_query_gpu.txt", 'r') as fin: + return fin.read() + else: + filter = nvidia_smi.__fromDeviceQueryString(filter) + else: + filter = list(filter) + + nvidia_smi_results = {} + dictResult = [] + try: + if (NVSMI_ALL in filter or NVSMI_TIMESTAMP in filter): + nvidia_smi_results['timestamp']=nvidia_smi.__toString(datetime.date.today()) + if (NVSMI_ALL in filter or NVSMI_DRIVER_VERSION in filter): + nvidia_smi_results['driver_version']=nvidia_smi.__toString(nvmlSystemGetDriverVersion()) + + deviceCount = nvmlDeviceGetCount() + if (NVSMI_ALL in filter or NVSMI_COUNT in filter): + nvidia_smi_results['count']=deviceCount + + for i in range(0, deviceCount): + gpuResults = {} + handle = self.__handles[i] + + pciInfo = nvmlDeviceGetPciInfo(handle) + + if (NVSMI_ALL in filter or NVSMI_PCI_BUS_ID in filter): + gpuResults['id']=nvidia_smi.__toString(pciInfo.busId) + if (NVSMI_ALL in filter or NVSMI_NAME in filter): + gpuResults['product_name']=nvidia_smi.__toString(nvmlDeviceGetName(handle)) + + try: + # if nvmlDeviceGetBrand() succeeds it is guaranteed to be in the dictionary + brandName = NVSMI_BRAND_NAMES[nvmlDeviceGetBrand(handle)] + except NVMLError as err: + brandName = nvidia_smi.__handleError(err) + + gpuResults['product_brand']=brandName + + + if (NVSMI_ALL in filter or NVSMI_DISPLAY_MODE in filter): + try: + state = ('Enabled' if (nvmlDeviceGetDisplayMode(handle) != 0) else 'Disabled') + except NVMLError as err: + state = nvidia_smi.__handleError(err) + + gpuResults['display_mode']=state + + if (NVSMI_ALL in filter or NVSMI_DISPLAY_ACTIVE in filter): + try: + state = ('Enabled' if (nvmlDeviceGetDisplayActive(handle) != 0) else 'Disabled') + except NVMLError as err: + state = nvidia_smi.__handleError(err) + + gpuResults['display_active']=state + + if (NVSMI_ALL in filter or NVSMI_PERSISTENCE_MODE in filter): + try: + mode = 'Enabled' if (nvmlDeviceGetPersistenceMode(handle) != 0) else 'Disabled' + except NVMLError as err: + mode = nvidia_smi.__handleError(err) + + gpuResults['persistence_mode']=mode + + migMode = {} + includeMigMode = False + if (NVSMI_ALL in filter or + NVSMI_MIG_MODE_CURRENT in filter or + NVSMI_MIG_MODE_PENDING in filter): + try: + (current, pending) = nvmlDeviceGetMigMode(handle) + except NVMLError as err: + current = nvidia_smi.__handleError(err) + pending = current + migMode['current_mm'] = 'Enabled' if current == NVML_DEVICE_MIG_ENABLE else 'Disabled' + migMode['pending_mm'] = 'Enabled' if pending == NVML_DEVICE_MIG_ENABLE else 'Disabled' + includeMigMode = True + + if includeMigMode: + gpuResults['mig_mode'] = migMode + + + if (NVSMI_ALL in filter or NVSMI_ACCT_MODE in filter): + try: + mode = 'Enabled' if (nvmlDeviceGetAccountingMode(handle) != 0) else 'Disabled' + except NVMLError as err: + mode = nvidia_smi.__handleError(err) + + gpuResults['accounting_mode']=mode + + if (NVSMI_ALL in filter or NVSMI_ACCT_BUFFER_SIZE in filter): + try: + bufferSize = nvidia_smi.__toString(nvmlDeviceGetAccountingBufferSize(handle)) + except NVMLError as err: + bufferSize = nvidia_smi.__handleError(err) + + gpuResults['accounting_mode_buffer_size']=bufferSize + + driverModel = {} + includeDriverModel = False + if (NVSMI_ALL in filter or NVSMI_DRIVER_MODEL_CUR in filter): + try: + current = 'WDDM' if (nvmlDeviceGetCurrentDriverModel(handle) == NVML_DRIVER_WDDM) else 'TCC' + except NVMLError as err: + current = nvidia_smi.__handleError(err) + driverModel['current_dm']=current + includeDriverModel = True + + if (NVSMI_ALL in filter or NVSMI_DRIVER_MODEL_PENDING in filter): + try: + pending = 'WDDM' if (nvmlDeviceGetPendingDriverModel(handle) == NVML_DRIVER_WDDM) else 'TCC' + except NVMLError as err: + pending = nvidia_smi.__handleError(err) + + driverModel['pending_dm'] = pending + includeDriverModel = True + + if includeDriverModel: + gpuResults['driver_model'] = driverModel + + if (NVSMI_ALL in filter or NVSMI_SERIALNUMBER in filter): + try: + serial = nvmlDeviceGetSerial(handle) + except NVMLError as err: + serial = nvidia_smi.__handleError(err) + + gpuResults['serial'] = nvidia_smi.__toString(serial) + + if (NVSMI_ALL in filter or NVSMI_UUID in filter): + try: + uuid = nvmlDeviceGetUUID(handle) + except NVMLError as err: + uuid = nvidia_smi.__handleError(err) + + gpuResults['uuid'] = nvidia_smi.__toString(uuid) + + if (NVSMI_ALL in filter or NVSMI_INDEX in filter): + try: + minor_number = nvmlDeviceGetMinorNumber(handle) + except NVMLError as err: + minor_number = nvidia_smi.__handleError(err) + + gpuResults['minor_number'] = nvidia_smi.__toString(minor_number) + + if (NVSMI_ALL in filter or NVSMI_VBIOS_VER in filter): + try: + vbios = nvmlDeviceGetVbiosVersion(handle) + except NVMLError as err: + vbios = nvidia_smi.__handleError(err) + + gpuResults['vbios_version'] = nvidia_smi.__toString(vbios) + + if (NVSMI_ALL in filter or NVSMI_VBIOS_VER in filter): + try: + multiGpuBool = nvmlDeviceGetMultiGpuBoard(handle) + except NVMLError as err: + multiGpuBool = nvidia_smi.__handleError(err); + + if multiGpuBool == "N/A": + gpuResults['multigpu_board'] = 'N/A' + elif multiGpuBool: + gpuResults['multigpu_board'] = 'Yes' + else: + gpuResults['multigpu_board'] = 'No' + + if (NVSMI_ALL in filter or NVSMI_BOARD_ID in filter): + try: + boardId = nvmlDeviceGetBoardId(handle) + except NVMLError as err: + boardId = nvidia_smi.__handleError(err) + + try: + hexBID = "0x%x" % boardId + except: + hexBID = boardId + + gpuResults['board_id'] = hexBID + + inforomVersion = {} + includeInforom = False + if (NVSMI_ALL in filter or NVSMI_INFOROM_IMG in filter): + try: + img = nvmlDeviceGetInforomImageVersion(handle) + except NVMLError as err: + img = nvidia_smi.__handleError(err) + + inforomVersion['img_version'] = nvidia_smi.__toString(img) + includeInforom = True + + if (NVSMI_ALL in filter or NVSMI_INFOROM_OEM in filter): + try: + oem = nvmlDeviceGetInforomVersion(handle, NVML_INFOROM_OEM) + except NVMLError as err: + oem = nvidia_smi.__handleError(err) + + inforomVersion['oem_object'] = nvidia_smi.__toString(oem) + includeInforom = True + + if (NVSMI_ALL in filter or NVSMI_INFOROM_ECC in filter): + try: + ecc = nvmlDeviceGetInforomVersion(handle, NVML_INFOROM_ECC) + except NVMLError as err: + ecc = nvidia_smi.__handleError(err) + + inforomVersion['ecc_object'] = nvidia_smi.__toString(ecc) + includeInforom = True + + if (NVSMI_ALL in filter or NVSMI_INFOROM_PWR in filter): + try: + pwr = nvmlDeviceGetInforomVersion(handle, NVML_INFOROM_POWER) + except NVMLError as err: + pwr = nvidia_smi.__handleError(err) + + inforomVersion['pwr_object'] = nvidia_smi.__toString(pwr) + includeInforom = True + + if includeInforom: + gpuResults['inforom_version'] = inforomVersion + + gpuOperationMode = {} + includeGOM = False + if (NVSMI_ALL in filter or NVSMI_GOM_CUR in filter): + try: + current = nvidia_smi.__toStrGOM(nvmlDeviceGetCurrentGpuOperationMode(handle)) + except NVMLError as err: + current = nvidia_smi.__handleError(err) + gpuOperationMode['current_gom'] = nvidia_smi.__toString(current) + includeGOM = True + + if (NVSMI_ALL in filter or NVSMI_GOM_PENDING in filter): + try: + pending = nvidia_smi.__toStrGOM(nvmlDeviceGetPendingGpuOperationMode(handle)) + except NVMLError as err: + pending = nvidia_smi.__handleError(err) + + gpuOperationMode['pending_gom'] = nvidia_smi.__toString(pending) + includeGOM = True + + if includeGOM: + gpuResults['gpu_operation_mode'] = gpuOperationMode + + pci = {} + includePci = False + + if (NVSMI_ALL in filter or NVSMI_PCI_BUS in filter): + pci['pci_bus'] = '%02X' % pciInfo.bus + includePci = True + + if (NVSMI_ALL in filter or NVSMI_PCI_DEVICE in filter): + pci['pci_device'] = '%02X' % pciInfo.device + includePci = True + + if (NVSMI_ALL in filter or NVSMI_PCI_DOMAIN in filter): + pci['pci_domain'] = '%04X' % pciInfo.domain + includePci = True + + if (NVSMI_ALL in filter or NVSMI_PCI_DEVICE_ID in filter): + pci['pci_device_id'] = '%08X' % (pciInfo.pciDeviceId) + includePci = True + + if (NVSMI_ALL in filter or NVSMI_PCI_BUS_ID in filter): + pci['pci_bus_id'] = nvidia_smi.__toString(pciInfo.busId) + includePci = True + + if (NVSMI_ALL in filter or NVSMI_PCI_SUBDEVICE_ID in filter): + pci['pci_sub_system_id'] = '%08X' % (pciInfo.pciSubSystemId) + includePci = True + + pciGpuLinkInfo = {} + includeLinkInfo = False + pciGen = {} + includeGen = False + + if (NVSMI_ALL in filter or NVSMI_PCI_LINK_GEN_MAX in filter): + try: + gen = nvidia_smi.__toString(nvmlDeviceGetMaxPcieLinkGeneration(handle)) + except NVMLError as err: + gen = nvidia_smi.__handleError(err) + + pciGen['max_link_gen'] = gen + includeGen = True + + if (NVSMI_ALL in filter or NVSMI_PCI_LINK_GEN_CUR in filter): + try: + gen = nvidia_smi.__toString(nvmlDeviceGetCurrPcieLinkGeneration(handle)) + except NVMLError as err: + gen = nvidia_smi.__handleError(err) + + pciGen['current_link_gen'] = gen + includeGen = True + + if includeGen: + pciGpuLinkInfo['pcie_gen'] = pciGen + includeLinkInfo = True + + pciLinkWidths = {} + includeLinkWidths = False + + if (NVSMI_ALL in filter or NVSMI_PCI_LINK_WIDTH_MAX in filter): + try: + width = nvidia_smi.__toString(nvmlDeviceGetMaxPcieLinkWidth(handle)) + 'x' + except NVMLError as err: + width = nvidia_smi.__handleError(err) + + pciLinkWidths['max_link_width'] = width + includeLinkWidths = True + + if (NVSMI_ALL in filter or NVSMI_PCI_LINK_WIDTH_CUR in filter): + try: + width = nvidia_smi.__toString(nvmlDeviceGetCurrPcieLinkWidth(handle)) + 'x' + except NVMLError as err: + width = nvidia_smi.__handleError(err) + + pciLinkWidths['current_link_width'] = width + includeLinkWidths = True + + if includeLinkWidths: + pciGpuLinkInfo['link_widths'] = pciLinkWidths + includeLinkInfo = True + + if includeLinkInfo: + pci['pci_gpu_link_info'] = pciGpuLinkInfo + includePci = True + + pciBridgeChip = {} + includeBridgeChip = False + + if (NVSMI_ALL in filter): + try: + bridgeHierarchy = nvmlDeviceGetBridgeChipInfo(handle) + bridge_type = '' + if bridgeHierarchy.bridgeChipInfo[0].type == 0: + bridge_type += 'PLX' + else: + bridge_type += 'BR04' + pciBridgeChip['bridge_chip_type'] = bridge_type + + if bridgeHierarchy.bridgeChipInfo[0].fwVersion == 0: + strFwVersion = 'N/A' + else: + strFwVersion = '%08X' % (bridgeHierarchy.bridgeChipInfo[0].fwVersion) + pciBridgeChip['bridge_chip_fw'] = nvidia_smi.__toString(strFwVersion) + except NVMLError as err: + pciBridgeChip['bridge_chip_type'] = nvidia_smi.__handleError(err) + pciBridgeChip['bridge_chip_fw'] = nvidia_smi.__handleError(err) + + includeBridgeChip = True + + if includeBridgeChip: + pci['pci_bridge_chip'] = pciBridgeChip + includePci = True + + if (NVSMI_ALL in filter): + try: + replay = nvmlDeviceGetPcieReplayCounter(handle) + pci['replay_counter'] = nvidia_smi.__toString(replay) + except NVMLError as err: + pci['replay_counter'] = nvidia_smi.__handleError(err) + includePci = True + + if (NVSMI_ALL in filter): + try: + tx_bytes = nvmlDeviceGetPcieThroughput(handle, NVML_PCIE_UTIL_TX_BYTES) + pci['tx_util'] = tx_bytes + pci['tx_util_unit'] = 'KB/s' + except NVMLError as err: + pci['tx_util'] = nvidia_smi.__handleError(err) + includePci = True + + if (NVSMI_ALL in filter): + try: + rx_bytes = nvmlDeviceGetPcieThroughput(handle, NVML_PCIE_UTIL_RX_BYTES) + pci['rx_util'] = rx_bytes + pci['rx_util_unit'] = 'KB/s' + except NVMLError as err: + pci['rx_util'] = nvidia_smi.__handleError(err) + includePci = True + + if includePci: + gpuResults['pci']= pci + + if (NVSMI_ALL in filter or NVSMI_FAN_SPEED in filter): + try: + fan = nvmlDeviceGetFanSpeed(handle) + except NVMLError as err: + fan = nvidia_smi.__handleError(err) + gpuResults['fan_speed']= fan + gpuResults['fan_speed_unit']= '%' + + if (NVSMI_ALL in filter or NVSMI_PSTATE in filter): + try: + perfState = nvmlDeviceGetPowerState(handle) + perfStateStr = 'P%s' % perfState + except NVMLError as err: + perfStateStr = nvidia_smi.__handleError(err) + gpuResults['performance_state']= perfStateStr + + + if (NVSMI_ALL in filter or + NVSMI_CLOCK_THROTTLE_REASONS_SUPPORTED in filter or + NVSMI_CLOCK_THROTTLE_REASONS_ACTIVE in filter or + NVSMI_CLOCK_THROTTLE_REASONS_IDLE in filter or + NVSMI_CLOCK_THROTTLE_REASONS_APP_SETTING in filter or + NVSMI_CLOCK_THROTTLE_REASONS_SW_PWR_CAP in filter or + NVSMI_CLOCK_THROTTLE_REASONS_HW_SLOWDOWN in filter or + NVSMI_CLOCK_THROTTLE_REASONS_HW_THERMAL_SLOWDOWN in filter or + NVSMI_CLOCK_THROTTLE_REASONS_HW_PWR_BRAKE_SLOWDOWN in filter or + NVSMI_CLOCK_THROTTLE_REASONS_SW_THERMAL_SLOWDOWN in filter or + NVSMI_CLOCK_THROTTLE_REASONS_SYNC_BOOST in filter): + gpuResults['clocks_throttle']= nvidia_smi.__GetClocksThrottleReasons(handle) + + fbMemoryUsage = {} + includeMemoryUsage = False + if (NVSMI_ALL in filter or + NVSMI_MEMORY_TOTAL in filter or + NVSMI_MEMORY_USED in filter or + NVSMI_MEMORY_FREE in filter): + + includeMemoryUsage = True + try: + memInfo = nvmlDeviceGetMemoryInfo(handle) + mem_total = memInfo.total / 1024 / 1024 + mem_used = memInfo.used / 1024 / 1024 + mem_free = memInfo.total / 1024 / 1024 - memInfo.used / 1024 / 1024 + except NVMLError as err: + error = nvidia_smi.__handleError(err) + mem_total = error + mem_used = error + mem_free = error + + if (NVSMI_ALL in filter or NVSMI_MEMORY_TOTAL in filter): + fbMemoryUsage['total']=mem_total + + if (NVSMI_ALL in filter or NVSMI_MEMORY_USED in filter): + fbMemoryUsage['used']=mem_used + + if (NVSMI_ALL in filter or NVSMI_MEMORY_FREE in filter): + fbMemoryUsage['free']=mem_free + + if includeMemoryUsage: + fbMemoryUsage['unit']='MiB' + gpuResults['fb_memory_usage'] = fbMemoryUsage + + if (NVSMI_ALL in filter or NVSMI_MEMORY_BAR1 in filter): + try: + memInfo = nvmlDeviceGetBAR1MemoryInfo(handle) + mem_total = memInfo.bar1Total / 1024 / 1024 + mem_used = memInfo.bar1Used / 1024 / 1024 + mem_free = memInfo.bar1Total / 1024 / 1024 - memInfo.bar1Used / 1024 / 1024 + except NVMLError as err: + error = nvidia_smi.__handleError(err) + mem_total = error + mem_used = error + mem_free = error + + bar1MemoryUsage = {} + bar1MemoryUsage['total']=mem_total + bar1MemoryUsage['used']=mem_used + bar1MemoryUsage['free']=mem_free + bar1MemoryUsage['unit']='MiB' + gpuResults['bar1_memory_usage'] = bar1MemoryUsage + + if (NVSMI_ALL in filter or NVSMI_COMPUTE_MODE in filter): + try: + mode = nvmlDeviceGetComputeMode(handle) + if mode == NVML_COMPUTEMODE_DEFAULT: + modeStr = 'Default' + elif mode == NVML_COMPUTEMODE_EXCLUSIVE_THREAD: + modeStr = 'Exclusive Thread' + elif mode == NVML_COMPUTEMODE_PROHIBITED: + modeStr = 'Prohibited' + elif mode == NVML_COMPUTEMODE_EXCLUSIVE_PROCESS: + modeStr = 'Exclusive_Process' + else: + modeStr = 'Unknown' + except NVMLError as err: + modeStr = nvidia_smi.__handleError(err) + + gpuResults['compute_mode'] = modeStr + + utilization = {} + includeUtilization = False + if (NVSMI_ALL in filter or + NVSMI_UTILIZATION_GPU in filter or + NVSMI_UTILIZATION_MEM in filter): + + try: + util = nvmlDeviceGetUtilizationRates(handle) + gpu_util = util.gpu + mem_util = util.memory + except NVMLError as err: + error = nvidia_smi.__handleError(err) + gpu_util = error + mem_util = error + + if (NVSMI_ALL in filter or NVSMI_UTILIZATION_GPU in filter): + utilization['gpu_util'] = gpu_util + + if (NVSMI_ALL in filter or NVSMI_UTILIZATION_MEM in filter): + utilization['memory_util'] = mem_util + + includeUtilization = True + + if (NVSMI_ALL in filter or NVSMI_UTILIZATION_ENCODER in filter): + try: + (util_int, ssize) = nvmlDeviceGetEncoderUtilization(handle) + encoder_util = util_int + except NVMLError as err: + error = nvidia_smi.__handleError(err) + encoder_util = error + + utilization['encoder_util'] = encoder_util + includeUtilization = True + + if (NVSMI_ALL in filter or NVSMI_UTILIZATION_DECODER in filter): + try: + (util_int, ssize) = nvmlDeviceGetDecoderUtilization(handle) + decoder_util = util_int + except NVMLError as err: + error = nvidia_smi.__handleError(err) + decoder_util = error + + utilization['decoder_util'] = decoder_util + includeUtilization = True + + if includeUtilization: + utilization['unit'] = '%' + gpuResults['utilization'] = utilization + + if (NVSMI_ALL in filter or + NVSMI_ECC_MODE_CUR in filter or + NVSMI_ECC_MODE_PENDING in filter): + try: + (current, pending) = nvmlDeviceGetEccMode(handle) + curr_str = 'Enabled' if (current != 0) else 'Disabled' + pend_str = 'Enabled' if (pending != 0) else 'Disabled' + except NVMLError as err: + error = nvidia_smi.__handleError(err) + curr_str = error + pend_str = error + + eccMode = {} + if (NVSMI_ALL in filter or NVSMI_ECC_MODE_CUR in filter): + eccMode['current_ecc'] = curr_str + + if (NVSMI_ALL in filter or NVSMI_ECC_MODE_PENDING in filter): + eccMode['pending_ecc'] = pend_str + + gpuResults['ecc_mode'] = eccMode + + + eccErrors,includeEccErrors = nvidia_smi.__GetEcc(handle, filter) + if includeEccErrors: + gpuResults['ecc_errors'] = eccErrors + + retiredPages, includeRetiredPages = nvidia_smi.__GetRetiredPages(handle, filter) + if includeRetiredPages: + gpuResults['retired_pages'] = retiredPages + + temperature = {} + includeTemperature = False + + if (NVSMI_ALL in filter or NVSMI_TEMPERATURE_GPU in filter): + try: + temp = nvmlDeviceGetTemperature(handle, NVML_TEMPERATURE_GPU) + except NVMLError as err: + temp = nvidia_smi.__handleError(err) + + temperature['gpu_temp'] = temp + includeTemperature = True + + try: + temp = nvmlDeviceGetTemperatureThreshold(handle, NVML_TEMPERATURE_THRESHOLD_SHUTDOWN) + except NVMLError as err: + temp = nvidia_smi.__handleError(err) + + temperature['gpu_temp_max_threshold'] = temp + includeTemperature = True + + try: + temp = nvmlDeviceGetTemperatureThreshold(handle, NVML_TEMPERATURE_THRESHOLD_SLOWDOWN) + except NVMLError as err: + temp = nvidia_smi.__handleError(err) + + temperature['gpu_temp_slow_threshold'] = temp + includeTemperature = True + + if includeTemperature: + temperature['unit'] = 'C' + gpuResults['temperature'] = temperature + + power_readings = {} + includePowerReadings = False + if (NVSMI_ALL in filter or NVSMI_POWER_MGMT in filter): + try: + powMan = nvmlDeviceGetPowerManagementMode(handle) + powManStr = 'Supported' if powMan != 0 else 'N/A' + except NVMLError as err: + powManStr = nvidia_smi.__handleError(err) + power_readings['power_management'] = powManStr + includePowerReadings = True + + if (NVSMI_ALL in filter or NVSMI_POWER_DRAW in filter): + try: + powDraw = nvmlDeviceGetPowerUsage(handle) / 1000.0 + powDrawStr = powDraw + except NVMLError as err: + powDrawStr = nvidia_smi.__handleError(err) + power_readings['power_draw'] = powDrawStr + includePowerReadings = True + + if (NVSMI_ALL in filter or NVSMI_POWER_LIMIT in filter): + try: + powLimit = (nvmlDeviceGetPowerManagementLimit(handle) / 1000.0) + powLimitStr = powLimit + except NVMLError as err: + powLimitStr = nvidia_smi.__handleError(err) + power_readings['power_limit'] = powLimitStr + includePowerReadings = True + + if (NVSMI_ALL in filter or NVSMI_POWER_LIMIT_DEFAULT in filter): + try: + powLimit = (nvmlDeviceGetPowerManagementDefaultLimit(handle) / 1000.0) + powLimitStr = powLimit + except NVMLError as err: + powLimitStr = nvidia_smi.__handleError(err) + power_readings['default_power_limit'] = powLimitStr + includePowerReadings = True + + if (NVSMI_ALL in filter or NVSMI_POWER_LIMIT_ENFORCED in filter): + try: + enforcedPowLimit = (nvmlDeviceGetEnforcedPowerLimit(handle) / 1000.0) + enforcedPowLimitStr = enforcedPowLimit + except NVMLError as err: + enforcedPowLimitStr = nvidia_smi.__handleError(err) + + power_readings['enforced_power_limit'] = enforcedPowLimitStr + includePowerReadings = True + + if (NVSMI_ALL in filter or + NVSMI_POWER_LIMIT_MIN in filter or + NVSMI_POWER_LIMIT_MAX in filter): + try: + powLimit = nvmlDeviceGetPowerManagementLimitConstraints(handle) + powLimitStrMin = powLimit[0] / 1000.0 + powLimitStrMax = powLimit[1] / 1000.0 + except NVMLError as err: + error = nvidia_smi.__handleError(err) + powLimitStrMin = error + powLimitStrMax = error + + if (NVSMI_ALL in filter or NVSMI_POWER_LIMIT_MIN in filter): + power_readings['min_power_limit'] = powLimitStrMin + if (NVSMI_ALL in filter or NVSMI_POWER_LIMIT_MAX in filter): + power_readings['max_power_limit'] = powLimitStrMax + includePowerReadings = True + + if includePowerReadings: + try: + perfState = 'P' + nvidia_smi.__toString(nvmlDeviceGetPowerState(handle)) + except NVMLError as err: + perfState = nvidia_smi.__handleError(err) + power_readings['power_state'] = perfState + + power_readings['unit'] = 'W' + gpuResults['power_readings'] = power_readings + + clocks = {} + includeClocks = False + if(NVSMI_ALL in filter or NVSMI_CLOCKS_GRAPHICS_CUR in filter): + try: + graphics = nvmlDeviceGetClockInfo(handle, NVML_CLOCK_GRAPHICS) + except NVMLError as err: + graphics = nvidia_smi.__handleError(err) + clocks['graphics_clock'] = graphics + includeClocks = True; + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_GRAPHICS_CUR in filter): + try: + sm = nvmlDeviceGetClockInfo(handle, NVML_CLOCK_SM) + except NVMLError as err: + sm = nvidia_smi.__handleError(err) + clocks['sm_clock'] = sm + includeClocks = True; + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_MEMORY_CUR in filter): + try: + mem = nvmlDeviceGetClockInfo(handle, NVML_CLOCK_MEM) + except NVMLError as err: + mem = nvidia_smi.__handleError(err) + clocks['mem_clock'] = mem + includeClocks = True; + + if includeClocks: + clocks['unit'] = 'MHz' + gpuResults['clocks'] = clocks + + applicationClocks = {} + includeAppClocks = False + if(NVSMI_ALL in filter or NVSMI_CLOCKS_APPL_GRAPHICS in filter): + try: + graphics = nvmlDeviceGetApplicationsClock(handle, NVML_CLOCK_GRAPHICS) + except NVMLError as err: + graphics = nvidia_smi.__handleError(err) + applicationClocks['graphics_clock'] = graphics + includeAppClocks = True + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_APPL_MEMORY in filter): + try: + mem = nvmlDeviceGetApplicationsClock(handle, NVML_CLOCK_MEM) + except NVMLError as err: + mem = nvidia_smi.__handleError(err) + applicationClocks['mem_clock'] = mem + includeAppClocks = True + + if includeAppClocks: + applicationClocks['unit'] = 'MHz' + gpuResults['applications_clocks'] = applicationClocks + + defaultApplicationClocks = {} + includeDefaultAppClocks = False + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_APPL_GRAPHICS_DEFAULT in filter): + try: + graphics = nvmlDeviceGetDefaultApplicationsClock(handle, NVML_CLOCK_GRAPHICS) + except NVMLError as err: + graphics = nvidia_smi.__handleError(err) + defaultApplicationClocks['graphics_clock'] = graphics + includeDefaultAppClocks = True + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_APPL_MEMORY_DEFAULT in filter): + try: + mem = nvmlDeviceGetDefaultApplicationsClock(handle, NVML_CLOCK_MEM) + except NVMLError as err: + mem = nvidia_smi.__handleError(err) + defaultApplicationClocks['mem_clock'] = mem + includeDefaultAppClocks = True + + if includeDefaultAppClocks: + defaultApplicationClocks['unit'] = 'MHz' + gpuResults['default_applications_clocks'] = defaultApplicationClocks + + maxClocks = {} + includeMaxClocks = False + if(NVSMI_ALL in filter or NVSMI_CLOCKS_GRAPHICS_MAX in filter): + try: + graphics = nvmlDeviceGetMaxClockInfo(handle, NVML_CLOCK_GRAPHICS) + except NVMLError as err: + graphics = nvidia_smi.__handleError(err) + maxClocks['graphics_clock'] = graphics + includeMaxClocks = True + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_SM_MAX in filter): + try: + sm = nvmlDeviceGetMaxClockInfo(handle, NVML_CLOCK_SM) + except NVMLError as err: + sm = nvidia_smi.__handleError(err) + maxClocks['sm_clock'] = sm + includeMaxClocks = True + + if(NVSMI_ALL in filter or NVSMI_CLOCKS_MEMORY_MAX in filter): + try: + mem = nvmlDeviceGetMaxClockInfo(handle, NVML_CLOCK_MEM) + except NVMLError as err: + mem = nvidia_smi.__handleError(err) + maxClocks['mem_clock'] = mem + includeMaxClocks = True + + if includeMaxClocks: + maxClocks['unit'] = 'MHz' + gpuResults['max_clocks'] = maxClocks + + if (NVSMI_ALL in filter or NVSMI_CLOCKS_POLICY in filter): + clockPolicy = {} + try: + boostedState, boostedDefaultState = nvmlDeviceGetAutoBoostedClocksEnabled(handle) + if boostedState == NVML_FEATURE_DISABLED: + autoBoostStr = "Off" + else: + autoBoostStr = "On" + + if boostedDefaultState == NVML_FEATURE_DISABLED: + autoBoostDefaultStr = "Off" + else: + autoBoostDefaultStr = "On" + + except NVMLError_NotSupported: + autoBoostStr = "N/A" + autoBoostDefaultStr = "N/A" + except NVMLError as err: + autoBoostStr = nvidia_smi.__handleError(err) + autoBoostDefaultStr = nvidia_smi.__handleError(err) + + clockPolicy['auto_boost'] = autoBoostStr + clockPolicy['auto_boost_default'] = autoBoostDefaultStr + gpuResults['clock_policy'] = clockPolicy + + if (NVSMI_ALL in filter or NVSMI_CLOCKS_SUPPORTED in filter): + supportedClocks = [] + try: + memClocks = nvmlDeviceGetSupportedMemoryClocks(handle) + # jj = 1 + for m in memClocks: + supportMemClock = {} + supportMemClock['current'] = m + supportMemClock['unit'] = 'MHz' + + supportedGraphicsClocks = [] + try: + clocks = nvmlDeviceGetSupportedGraphicsClocks(handle, m) + for c in clocks: + supportedGraphicsClocks.append(c) + except NVMLError as err: + supportedGraphicsClocks = nvidia_smi.__handleError(err) + + supportMemClock['supported_graphics_clock'] = supportedGraphicsClocks + + supportedClocks.append( supportMemClock ) + # jj+=1 + + except NVMLError as err: + supportedClocks['Error'] = nvidia_smi.__handleError(err) + + gpuResults['supported_clocks'] = supportedClocks if len(supportedClocks) > 0 else None + + if (NVSMI_ALL in filter or NVSMI_COMPUTE_APPS in filter): + processes = [] + try: + procs = nvmlDeviceGetComputeRunningProcesses(handle) + + # ii = 1 + for p in procs: + try: + name = nvidia_smi.__toString(nvmlSystemGetProcessName(p.pid)) + except NVMLError as err: + if (err.value == NVML_ERROR_NOT_FOUND): + # probably went away + continue + else: + name = nvidia_smi.__handleError(err) + processInfo = {} + processInfo['pid'] = p.pid + processInfo['process_name'] = name + + if (p.usedGpuMemory == None): + mem = 0 + else: + mem = int(p.usedGpuMemory / 1024 / 1024) + processInfo['used_memory'] = mem + processInfo['unit'] = 'MiB' + processes.append( processInfo ) +# ii+=1 + + except NVMLError as err: + processes = nvidia_smi.__handleError(err) + + gpuResults['processes'] = processes if len(processes) > 0 else None + + if (NVSMI_ALL in filter or NVSMI_ACCOUNTED_APPS in filter): + try: + pids = nvmlDeviceGetAccountingPids(handle) + + accountProcess = [] +# ii = 1 + for pid in pids : + try: + stats = nvmlDeviceGetAccountingStats(handle, pid) + gpuUtilization = "%d %%" % stats.gpuUtilization + memoryUtilization = "%d %%" % stats.memoryUtilization + if (stats.maxMemoryUsage == None): + maxMemoryUsage = 'N/A' + else: + maxMemoryUsage = '%d MiB' % (stats.maxMemoryUsage / 1024 / 1024) + time = "%d ms" % stats.time + is_running = "%d" % stats.isRunning + except NVMLError as err: + if (err.value == NVML_ERROR_NOT_FOUND): + # probably went away + continue + err = nvidia_smi.__handleError(err) + gpuUtilization = err + memoryUtilization = err + maxMemoryUsage = err + time = err + is_running = err + + accountProcessInfo = {} + accountProcessInfo['pid'] = '%d' % pid + accountProcessInfo['gpu_util'] = gpuUtilization + accountProcessInfo['memory_util'] = memoryUtilization + accountProcessInfo['max_memory_usage'] = maxMemoryUsage + accountProcessInfo['time'] = time + accountProcessInfo['is_running'] = is_running + + accountProcess.append( accountProcessInfo ) + + gpuResults['accounted_processes'] = accountProcess if len(accountProcess) > 0 else None +# ii+=1 + except NVMLError as err: + gpuResults['accounted_processes'] = nvidia_smi.__handleError(err) + + + if (len(gpuResults) > 0): + dictResult.append(gpuResults) + + if (len(dictResult) > 0): + nvidia_smi_results['gpu']=dictResult + + except NVMLError as err: + print( 'nvidia_smi.py: ' + err.__str__() + '\n' ) + + return nvidia_smi_results + + def __to_str_dictionary(self, value, indent): + strResults = '' + try: + for key,val in value.items(): + if isinstance(val, collections.Mapping): + if len(val.values()) > 0: + strResults += ("%s%s:\n")%(indent,key) + strResults += self.__to_str_dictionary(val, ' '+indent) + else: + strResults += ("%s%s: %s\n")%(indent,key,"None") + elif (type(val) is list) and (isinstance(val[0], collections.Mapping)): + for i in range(0,len(val)): + strResults += ("%s%s: [%d of %d]\n")%(indent,key, i+1,len(val)) + strResults += self.__to_str_dictionary(val[i],' '+indent) + else: + strResults += ("%s%s: %s\n")%(indent,key, str(val)) + + except Exception as e: + strResults += "\n[Error] " + str(e) + + return strResults + + def __to_str(self, results): + strResults = '' + indent = ' ' + for key,val in results.items(): + if type(val) is list: + for i in range(0,len(val)): + strResults += ("%s%s: [%d of %d]\n")%(indent,key, i+1,len(val)) + strResults += self.__to_str_dictionary(val[i],' '+indent) + else: + strResults += ("%s%s: %s\n")%(indent,key, str(val)) + + return strResults + + def format(self, results): + + if type(results) is str: + return results + + return self.__to_str(results) + +# this is not exectued when module is imported +if __name__ == "__main__": + def main(): + #evaluate arguments + as_xml = False + query_gpu_args = None + for i in range(1,len(sys.argv)): + v = sys.argv[i] + if (v.lower() == "xml"): + as_xml = True + else : + query_gpu_args = v.lower() + + #execute device query + nvsmi = nvidia_smi.getInstance() + if (as_xml): + results = nvsmi.XmlDeviceQuery(query_gpu_args) + else: + results = nvsmi.DeviceQuery(query_gpu_args) + + print(nvsmi.format(results)) + + main() diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..c864c56 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,15 @@ +[metadata] +license_file = LICENSE.txt + +[versioneer] +VCS = git +style = pep440 +versionfile_source = pynvml/_version.py +versionfile_build = pynvml/_version.py +tag_prefix = +parentdir_prefix = pynvml- + +[egg_info] +tag_build = +tag_date = 0 + diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..9f7b3a4 --- /dev/null +++ b/setup.py @@ -0,0 +1,44 @@ +from setuptools import setup, find_packages +from os import path +from io import open + +import versioneer + +here = path.abspath(path.dirname(__file__)) + +# Get the long description from the README file +with open(path.join(here, 'README.md'), encoding='utf-8') as f: + long_description = f.read() + +# earlier versions don't support all classifiers +#if version < '2.2.3': +# from distutils.dist import DistributionMetadata +# DistributionMetadata.classifiers = None +# DistributionMetadata.download_url = None + +setup(name='pynvml', + version=versioneer.get_version(), + cmdclass=versioneer.get_cmdclass(), + python_requires='>=3.6', + description='Python Bindings for the NVIDIA Management Library', + long_description=long_description, + long_description_content_type='text/markdown', + packages=find_packages(exclude=['notebooks', 'docs', 'tests']), + package_data={'pynvml': ['README.md','help_query_gpu.txt']}, + license="BSD", + url="http://www.nvidia.com/", + author="NVIDIA Corporation", + author_email="rzamora@nvidia.com", + classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: BSD License', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python', + 'Topic :: Software Development :: Libraries :: Python Modules', + 'Topic :: System :: Hardware', + 'Topic :: System :: Systems Administration', + ], + ) diff --git a/versioneer.py b/versioneer.py new file mode 100644 index 0000000..64fea1c --- /dev/null +++ b/versioneer.py @@ -0,0 +1,1822 @@ + +# Version: 0.18 + +"""The Versioneer - like a rocketeer, but for versions. + +The Versioneer +============== + +* like a rocketeer, but for versions! +* https://github.com/warner/python-versioneer +* Brian Warner +* License: Public Domain +* Compatible With: python2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, and pypy +* [![Latest Version] +(https://pypip.in/version/versioneer/badge.svg?style=flat) +](https://pypi.python.org/pypi/versioneer/) +* [![Build Status] +(https://travis-ci.org/warner/python-versioneer.png?branch=master) +](https://travis-ci.org/warner/python-versioneer) + +This is a tool for managing a recorded version number in distutils-based +python projects. The goal is to remove the tedious and error-prone "update +the embedded version string" step from your release process. Making a new +release should be as easy as recording a new tag in your version-control +system, and maybe making new tarballs. + + +## Quick Install + +* `pip install versioneer` to somewhere to your $PATH +* add a `[versioneer]` section to your setup.cfg (see below) +* run `versioneer install` in your source tree, commit the results + +## Version Identifiers + +Source trees come from a variety of places: + +* a version-control system checkout (mostly used by developers) +* a nightly tarball, produced by build automation +* a snapshot tarball, produced by a web-based VCS browser, like github's + "tarball from tag" feature +* a release tarball, produced by "setup.py sdist", distributed through PyPI + +Within each source tree, the version identifier (either a string or a number, +this tool is format-agnostic) can come from a variety of places: + +* ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows + about recent "tags" and an absolute revision-id +* the name of the directory into which the tarball was unpacked +* an expanded VCS keyword ($Id$, etc) +* a `_version.py` created by some earlier build step + +For released software, the version identifier is closely related to a VCS +tag. Some projects use tag names that include more than just the version +string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool +needs to strip the tag prefix to extract the version identifier. For +unreleased software (between tags), the version identifier should provide +enough information to help developers recreate the same tree, while also +giving them an idea of roughly how old the tree is (after version 1.2, before +version 1.3). Many VCS systems can report a description that captures this, +for example `git describe --tags --dirty --always` reports things like +"0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the +0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has +uncommitted changes. + +The version identifier is used for multiple purposes: + +* to allow the module to self-identify its version: `myproject.__version__` +* to choose a name and prefix for a 'setup.py sdist' tarball + +## Theory of Operation + +Versioneer works by adding a special `_version.py` file into your source +tree, where your `__init__.py` can import it. This `_version.py` knows how to +dynamically ask the VCS tool for version information at import time. + +`_version.py` also contains `$Revision$` markers, and the installation +process marks `_version.py` to have this marker rewritten with a tag name +during the `git archive` command. As a result, generated tarballs will +contain enough information to get the proper version. + +To allow `setup.py` to compute a version too, a `versioneer.py` is added to +the top level of your source tree, next to `setup.py` and the `setup.cfg` +that configures it. This overrides several distutils/setuptools commands to +compute the version when invoked, and changes `setup.py build` and `setup.py +sdist` to replace `_version.py` with a small static file that contains just +the generated version data. + +## Installation + +See [INSTALL.md](./INSTALL.md) for detailed installation instructions. + +## Version-String Flavors + +Code which uses Versioneer can learn about its version string at runtime by +importing `_version` from your main `__init__.py` file and running the +`get_versions()` function. From the "outside" (e.g. in `setup.py`), you can +import the top-level `versioneer.py` and run `get_versions()`. + +Both functions return a dictionary with different flavors of version +information: + +* `['version']`: A condensed version string, rendered using the selected + style. This is the most commonly used value for the project's version + string. The default "pep440" style yields strings like `0.11`, + `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section + below for alternative styles. + +* `['full-revisionid']`: detailed revision identifier. For Git, this is the + full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac". + +* `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the + commit date in ISO 8601 format. This will be None if the date is not + available. + +* `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that + this is only accurate if run in a VCS checkout, otherwise it is likely to + be False or None + +* `['error']`: if the version string could not be computed, this will be set + to a string describing the problem, otherwise it will be None. It may be + useful to throw an exception in setup.py if this is set, to avoid e.g. + creating tarballs with a version string of "unknown". + +Some variants are more useful than others. Including `full-revisionid` in a +bug report should allow developers to reconstruct the exact code being tested +(or indicate the presence of local changes that should be shared with the +developers). `version` is suitable for display in an "about" box or a CLI +`--version` output: it can be easily compared against release notes and lists +of bugs fixed in various releases. + +The installer adds the following text to your `__init__.py` to place a basic +version in `YOURPROJECT.__version__`: + + from ._version import get_versions + __version__ = get_versions()['version'] + del get_versions + +## Styles + +The setup.cfg `style=` configuration controls how the VCS information is +rendered into a version string. + +The default style, "pep440", produces a PEP440-compliant string, equal to the +un-prefixed tag name for actual releases, and containing an additional "local +version" section with more detail for in-between builds. For Git, this is +TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags +--dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the +tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and +that this commit is two revisions ("+2") beyond the "0.11" tag. For released +software (exactly equal to a known tag), the identifier will only contain the +stripped tag, e.g. "0.11". + +Other styles are available. See [details.md](details.md) in the Versioneer +source tree for descriptions. + +## Debugging + +Versioneer tries to avoid fatal errors: if something goes wrong, it will tend +to return a version of "0+unknown". To investigate the problem, run `setup.py +version`, which will run the version-lookup code in a verbose mode, and will +display the full contents of `get_versions()` (including the `error` string, +which may help identify what went wrong). + +## Known Limitations + +Some situations are known to cause problems for Versioneer. This details the +most significant ones. More can be found on Github +[issues page](https://github.com/warner/python-versioneer/issues). + +### Subprojects + +Versioneer has limited support for source trees in which `setup.py` is not in +the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are +two common reasons why `setup.py` might not be in the root: + +* Source trees which contain multiple subprojects, such as + [Buildbot](https://github.com/buildbot/buildbot), which contains both + "master" and "slave" subprojects, each with their own `setup.py`, + `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI + distributions (and upload multiple independently-installable tarballs). +* Source trees whose main purpose is to contain a C library, but which also + provide bindings to Python (and perhaps other langauges) in subdirectories. + +Versioneer will look for `.git` in parent directories, and most operations +should get the right version string. However `pip` and `setuptools` have bugs +and implementation details which frequently cause `pip install .` from a +subproject directory to fail to find a correct version string (so it usually +defaults to `0+unknown`). + +`pip install --editable .` should work correctly. `setup.py install` might +work too. + +Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in +some later version. + +[Bug #38](https://github.com/warner/python-versioneer/issues/38) is tracking +this issue. The discussion in +[PR #61](https://github.com/warner/python-versioneer/pull/61) describes the +issue from the Versioneer side in more detail. +[pip PR#3176](https://github.com/pypa/pip/pull/3176) and +[pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve +pip to let Versioneer work correctly. + +Versioneer-0.16 and earlier only looked for a `.git` directory next to the +`setup.cfg`, so subprojects were completely unsupported with those releases. + +### Editable installs with setuptools <= 18.5 + +`setup.py develop` and `pip install --editable .` allow you to install a +project into a virtualenv once, then continue editing the source code (and +test) without re-installing after every change. + +"Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a +convenient way to specify executable scripts that should be installed along +with the python package. + +These both work as expected when using modern setuptools. When using +setuptools-18.5 or earlier, however, certain operations will cause +`pkg_resources.DistributionNotFound` errors when running the entrypoint +script, which must be resolved by re-installing the package. This happens +when the install happens with one version, then the egg_info data is +regenerated while a different version is checked out. Many setup.py commands +cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into +a different virtualenv), so this can be surprising. + +[Bug #83](https://github.com/warner/python-versioneer/issues/83) describes +this one, but upgrading to a newer version of setuptools should probably +resolve it. + +### Unicode version strings + +While Versioneer works (and is continually tested) with both Python 2 and +Python 3, it is not entirely consistent with bytes-vs-unicode distinctions. +Newer releases probably generate unicode version strings on py2. It's not +clear that this is wrong, but it may be surprising for applications when then +write these strings to a network connection or include them in bytes-oriented +APIs like cryptographic checksums. + +[Bug #71](https://github.com/warner/python-versioneer/issues/71) investigates +this question. + + +## Updating Versioneer + +To upgrade your project to a new release of Versioneer, do the following: + +* install the new Versioneer (`pip install -U versioneer` or equivalent) +* edit `setup.cfg`, if necessary, to include any new configuration settings + indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details. +* re-run `versioneer install` in your source tree, to replace + `SRC/_version.py` +* commit any changed files + +## Future Directions + +This tool is designed to make it easily extended to other version-control +systems: all VCS-specific components are in separate directories like +src/git/ . The top-level `versioneer.py` script is assembled from these +components by running make-versioneer.py . In the future, make-versioneer.py +will take a VCS name as an argument, and will construct a version of +`versioneer.py` that is specific to the given VCS. It might also take the +configuration arguments that are currently provided manually during +installation by editing setup.py . Alternatively, it might go the other +direction and include code from all supported VCS systems, reducing the +number of intermediate scripts. + + +## License + +To make Versioneer easier to embed, all its code is dedicated to the public +domain. The `_version.py` that it creates is also in the public domain. +Specifically, both are released under the Creative Commons "Public Domain +Dedication" license (CC0-1.0), as described in +https://creativecommons.org/publicdomain/zero/1.0/ . + +""" + +from __future__ import print_function +try: + import configparser +except ImportError: + import ConfigParser as configparser +import errno +import json +import os +import re +import subprocess +import sys + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + +def get_root(): + """Get the project root directory. + + We require that all commands are run from the project root, i.e. the + directory that contains setup.py, setup.cfg, and versioneer.py . + """ + root = os.path.realpath(os.path.abspath(os.getcwd())) + setup_py = os.path.join(root, "setup.py") + versioneer_py = os.path.join(root, "versioneer.py") + if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): + # allow 'python path/to/setup.py COMMAND' + root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) + setup_py = os.path.join(root, "setup.py") + versioneer_py = os.path.join(root, "versioneer.py") + if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): + err = ("Versioneer was unable to run the project root directory. " + "Versioneer requires setup.py to be executed from " + "its immediate directory (like 'python setup.py COMMAND'), " + "or in a way that lets it use sys.argv[0] to find the root " + "(like 'python path/to/setup.py COMMAND').") + raise VersioneerBadRootError(err) + try: + # Certain runtime workflows (setup.py install/develop in a setuptools + # tree) execute all dependencies in a single python process, so + # "versioneer" may be imported multiple times, and python's shared + # module-import table will cache the first one. So we can't use + # os.path.dirname(__file__), as that will find whichever + # versioneer.py was first imported, even in later projects. + me = os.path.realpath(os.path.abspath(__file__)) + me_dir = os.path.normcase(os.path.splitext(me)[0]) + vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) + if me_dir != vsr_dir: + print("Warning: build in %s is using versioneer.py from %s" + % (os.path.dirname(me), versioneer_py)) + except NameError: + pass + return root + + +def get_config_from_root(root): + """Read the project setup.cfg file to determine Versioneer config.""" + # This might raise EnvironmentError (if setup.cfg is missing), or + # configparser.NoSectionError (if it lacks a [versioneer] section), or + # configparser.NoOptionError (if it lacks "VCS="). See the docstring at + # the top of versioneer.py for instructions on writing your setup.cfg . + setup_cfg = os.path.join(root, "setup.cfg") + parser = configparser.SafeConfigParser() + with open(setup_cfg, "r") as f: + parser.readfp(f) + VCS = parser.get("versioneer", "VCS") # mandatory + + def get(parser, name): + if parser.has_option("versioneer", name): + return parser.get("versioneer", name) + return None + cfg = VersioneerConfig() + cfg.VCS = VCS + cfg.style = get(parser, "style") or "" + cfg.versionfile_source = get(parser, "versionfile_source") + cfg.versionfile_build = get(parser, "versionfile_build") + cfg.tag_prefix = get(parser, "tag_prefix") + if cfg.tag_prefix in ("''", '""'): + cfg.tag_prefix = "" + cfg.parentdir_prefix = get(parser, "parentdir_prefix") + cfg.verbose = get(parser, "verbose") + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +# these dictionaries contain VCS-specific tools +LONG_VERSION_PY = {} +HANDLERS = {} + + +def register_vcs_handler(vcs, method): # decorator + """Decorator to mark a method as the handler for a particular VCS.""" + def decorate(f): + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, + env=None): + """Call the given command(s).""" + assert isinstance(commands, list) + p = None + for c in commands: + try: + dispcmd = str([c] + args) + # remember shell=False, so use git.cmd on windows, not just git + p = subprocess.Popen([c] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None)) + break + except EnvironmentError: + e = sys.exc_info()[1] + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %s" % (commands,)) + return None, None + stdout = p.communicate()[0].strip() + if sys.version_info[0] >= 3: + stdout = stdout.decode() + if p.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, p.returncode + return stdout, p.returncode + + +LONG_VERSION_PY['git'] = ''' +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. Generated by +# versioneer-0.18 (https://github.com/warner/python-versioneer) + +"""Git implementation of _version.py.""" + +import errno +import os +import re +import subprocess +import sys + + +def get_keywords(): + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" + git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" + git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + +def get_config(): + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "%(STYLE)s" + cfg.tag_prefix = "%(TAG_PREFIX)s" + cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s" + cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +LONG_VERSION_PY = {} +HANDLERS = {} + + +def register_vcs_handler(vcs, method): # decorator + """Decorator to mark a method as the handler for a particular VCS.""" + def decorate(f): + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, + env=None): + """Call the given command(s).""" + assert isinstance(commands, list) + p = None + for c in commands: + try: + dispcmd = str([c] + args) + # remember shell=False, so use git.cmd on windows, not just git + p = subprocess.Popen([c] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None)) + break + except EnvironmentError: + e = sys.exc_info()[1] + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %%s" %% dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %%s" %% (commands,)) + return None, None + stdout = p.communicate()[0].strip() + if sys.version_info[0] >= 3: + stdout = stdout.decode() + if p.returncode != 0: + if verbose: + print("unable to run %%s (error)" %% dispcmd) + print("stdout was %%s" %% stdout) + return None, p.returncode + return stdout, p.returncode + + +def versions_from_parentdir(parentdir_prefix, root, verbose): + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for i in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + else: + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %%s but none started with prefix %%s" %% + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs): + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords = {} + try: + f = open(versionfile_abs, "r") + for line in f.readlines(): + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + f.close() + except EnvironmentError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords(keywords, tag_prefix, verbose): + """Get version information from git keywords.""" + if not keywords: + raise NotThisMethod("no keywords at all, weird") + date = keywords.get("date") + if date is not None: + # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = set([r.strip() for r in refnames.strip("()").split(",")]) + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %%d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = set([r for r in refs if re.search(r'\d', r)]) + if verbose: + print("discarding '%%s', no digits" %% ",".join(refs - tags)) + if verbose: + print("likely tags: %%s" %% ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + if verbose: + print("picking %%s" %% r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=True) + if rc != 0: + if verbose: + print("Directory %%s not under git control" %% root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty", + "--always", "--long", + "--match", "%%s*" %% tag_prefix], + cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparseable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%%s'" + %% describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%%s' doesn't start with prefix '%%s'" + print(fmt %% (full_tag, tag_prefix)) + pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'" + %% (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], + cwd=root) + pieces["distance"] = int(count_out) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = run_command(GITS, ["show", "-s", "--format=%%ci", "HEAD"], + cwd=root)[0].strip() + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def plus_or_dot(pieces): + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces): + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_pre(pieces): + """TAG[.post.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post.devDISTANCE + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += ".post.dev%%d" %% pieces["distance"] + else: + # exception #1 + rendered = "0.post.dev%%d" %% pieces["distance"] + return rendered + + +def render_pep440_post(pieces): + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%%s" %% pieces["short"] + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%%s" %% pieces["short"] + return rendered + + +def render_pep440_old(pieces): + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Eexceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces): + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces): + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces, style): + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%%s'" %% style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +def get_versions(): + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for i in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} +''' + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs): + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords = {} + try: + f = open(versionfile_abs, "r") + for line in f.readlines(): + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + f.close() + except EnvironmentError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords(keywords, tag_prefix, verbose): + """Get version information from git keywords.""" + if not keywords: + raise NotThisMethod("no keywords at all, weird") + date = keywords.get("date") + if date is not None: + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = set([r.strip() for r in refnames.strip("()").split(",")]) + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = set([r for r in refs if re.search(r'\d', r)]) + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=True) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty", + "--always", "--long", + "--match", "%s*" % tag_prefix], + cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparseable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], + cwd=root) + pieces["distance"] = int(count_out) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], + cwd=root)[0].strip() + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def do_vcs_install(manifest_in, versionfile_source, ipy): + """Git-specific installation logic for Versioneer. + + For Git, this means creating/changing .gitattributes to mark _version.py + for export-subst keyword substitution. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + files = [manifest_in, versionfile_source] + if ipy: + files.append(ipy) + try: + me = __file__ + if me.endswith(".pyc") or me.endswith(".pyo"): + me = os.path.splitext(me)[0] + ".py" + versioneer_file = os.path.relpath(me) + except NameError: + versioneer_file = "versioneer.py" + files.append(versioneer_file) + present = False + try: + f = open(".gitattributes", "r") + for line in f.readlines(): + if line.strip().startswith(versionfile_source): + if "export-subst" in line.strip().split()[1:]: + present = True + f.close() + except EnvironmentError: + pass + if not present: + f = open(".gitattributes", "a+") + f.write("%s export-subst\n" % versionfile_source) + f.close() + files.append(".gitattributes") + run_command(GITS, ["add", "--"] + files) + + +def versions_from_parentdir(parentdir_prefix, root, verbose): + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for i in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + else: + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +SHORT_VERSION_PY = """ +# This file was generated by 'versioneer.py' (0.18) from +# revision-control system data, or from the parent directory name of an +# unpacked source archive. Distribution tarballs contain a pre-generated copy +# of this file. + +import json + +version_json = ''' +%s +''' # END VERSION_JSON + + +def get_versions(): + return json.loads(version_json) +""" + + +def versions_from_file(filename): + """Try to determine the version from _version.py if present.""" + try: + with open(filename) as f: + contents = f.read() + except EnvironmentError: + raise NotThisMethod("unable to read _version.py") + mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) + if not mo: + mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) + if not mo: + raise NotThisMethod("no version_json in _version.py") + return json.loads(mo.group(1)) + + +def write_to_version_file(filename, versions): + """Write the given version number to the given _version.py file.""" + os.unlink(filename) + contents = json.dumps(versions, sort_keys=True, + indent=1, separators=(",", ": ")) + with open(filename, "w") as f: + f.write(SHORT_VERSION_PY % contents) + + print("set %s to '%s'" % (filename, versions["version"])) + + +def plus_or_dot(pieces): + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces): + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_pre(pieces): + """TAG[.post.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post.devDISTANCE + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += ".post.dev%d" % pieces["distance"] + else: + # exception #1 + rendered = "0.post.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces): + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_old(pieces): + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Eexceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces): + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces): + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces, style): + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +class VersioneerBadRootError(Exception): + """The project root directory is unknown or missing key files.""" + + +def get_versions(verbose=False): + """Get the project version from whatever source is available. + + Returns dict with two keys: 'version' and 'full'. + """ + if "versioneer" in sys.modules: + # see the discussion in cmdclass.py:get_cmdclass() + del sys.modules["versioneer"] + + root = get_root() + cfg = get_config_from_root(root) + + assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" + handlers = HANDLERS.get(cfg.VCS) + assert handlers, "unrecognized VCS '%s'" % cfg.VCS + verbose = verbose or cfg.verbose + assert cfg.versionfile_source is not None, \ + "please set versioneer.versionfile_source" + assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" + + versionfile_abs = os.path.join(root, cfg.versionfile_source) + + # extract version from first of: _version.py, VCS command (e.g. 'git + # describe'), parentdir. This is meant to work for developers using a + # source checkout, for users of a tarball created by 'setup.py sdist', + # and for users of a tarball/zipball created by 'git archive' or github's + # download-from-tag feature or the equivalent in other VCSes. + + get_keywords_f = handlers.get("get_keywords") + from_keywords_f = handlers.get("keywords") + if get_keywords_f and from_keywords_f: + try: + keywords = get_keywords_f(versionfile_abs) + ver = from_keywords_f(keywords, cfg.tag_prefix, verbose) + if verbose: + print("got version from expanded keyword %s" % ver) + return ver + except NotThisMethod: + pass + + try: + ver = versions_from_file(versionfile_abs) + if verbose: + print("got version from file %s %s" % (versionfile_abs, ver)) + return ver + except NotThisMethod: + pass + + from_vcs_f = handlers.get("pieces_from_vcs") + if from_vcs_f: + try: + pieces = from_vcs_f(cfg.tag_prefix, root, verbose) + ver = render(pieces, cfg.style) + if verbose: + print("got version from VCS %s" % ver) + return ver + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + if verbose: + print("got version from parentdir %s" % ver) + return ver + except NotThisMethod: + pass + + if verbose: + print("unable to compute version") + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, "error": "unable to compute version", + "date": None} + + +def get_version(): + """Get the short version string for this project.""" + return get_versions()["version"] + + +def get_cmdclass(): + """Get the custom setuptools/distutils subclasses used by Versioneer.""" + if "versioneer" in sys.modules: + del sys.modules["versioneer"] + # this fixes the "python setup.py develop" case (also 'install' and + # 'easy_install .'), in which subdependencies of the main project are + # built (using setup.py bdist_egg) in the same python process. Assume + # a main project A and a dependency B, which use different versions + # of Versioneer. A's setup.py imports A's Versioneer, leaving it in + # sys.modules by the time B's setup.py is executed, causing B to run + # with the wrong versioneer. Setuptools wraps the sub-dep builds in a + # sandbox that restores sys.modules to it's pre-build state, so the + # parent is protected against the child's "import versioneer". By + # removing ourselves from sys.modules here, before the child build + # happens, we protect the child from the parent's versioneer too. + # Also see https://github.com/warner/python-versioneer/issues/52 + + cmds = {} + + # we add "version" to both distutils and setuptools + from distutils.core import Command + + class cmd_version(Command): + description = "report generated version string" + user_options = [] + boolean_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + vers = get_versions(verbose=True) + print("Version: %s" % vers["version"]) + print(" full-revisionid: %s" % vers.get("full-revisionid")) + print(" dirty: %s" % vers.get("dirty")) + print(" date: %s" % vers.get("date")) + if vers["error"]: + print(" error: %s" % vers["error"]) + cmds["version"] = cmd_version + + # we override "build_py" in both distutils and setuptools + # + # most invocation pathways end up running build_py: + # distutils/build -> build_py + # distutils/install -> distutils/build ->.. + # setuptools/bdist_wheel -> distutils/install ->.. + # setuptools/bdist_egg -> distutils/install_lib -> build_py + # setuptools/install -> bdist_egg ->.. + # setuptools/develop -> ? + # pip install: + # copies source tree to a tempdir before running egg_info/etc + # if .git isn't copied too, 'git describe' will fail + # then does setup.py bdist_wheel, or sometimes setup.py install + # setup.py egg_info -> ? + + # we override different "build_py" commands for both environments + if "setuptools" in sys.modules: + from setuptools.command.build_py import build_py as _build_py + else: + from distutils.command.build_py import build_py as _build_py + + class cmd_build_py(_build_py): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_py.run(self) + # now locate _version.py in the new build/ directory and replace + # it with an updated value + if cfg.versionfile_build: + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + cmds["build_py"] = cmd_build_py + + if "cx_Freeze" in sys.modules: # cx_freeze enabled? + from cx_Freeze.dist import build_exe as _build_exe + # nczeczulin reports that py2exe won't like the pep440-style string + # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. + # setup(console=[{ + # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION + # "product_version": versioneer.get_version(), + # ... + + class cmd_build_exe(_build_exe): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _build_exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + cmds["build_exe"] = cmd_build_exe + del cmds["build_py"] + + if 'py2exe' in sys.modules: # py2exe enabled? + try: + from py2exe.distutils_buildexe import py2exe as _py2exe # py3 + except ImportError: + from py2exe.build_exe import py2exe as _py2exe # py2 + + class cmd_py2exe(_py2exe): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _py2exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + cmds["py2exe"] = cmd_py2exe + + # we override different "sdist" commands for both environments + if "setuptools" in sys.modules: + from setuptools.command.sdist import sdist as _sdist + else: + from distutils.command.sdist import sdist as _sdist + + class cmd_sdist(_sdist): + def run(self): + versions = get_versions() + self._versioneer_generated_versions = versions + # unless we update this, the command will keep using the old + # version + self.distribution.metadata.version = versions["version"] + return _sdist.run(self) + + def make_release_tree(self, base_dir, files): + root = get_root() + cfg = get_config_from_root(root) + _sdist.make_release_tree(self, base_dir, files) + # now locate _version.py in the new base_dir directory + # (remembering that it may be a hardlink) and replace it with an + # updated value + target_versionfile = os.path.join(base_dir, cfg.versionfile_source) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, + self._versioneer_generated_versions) + cmds["sdist"] = cmd_sdist + + return cmds + + +CONFIG_ERROR = """ +setup.cfg is missing the necessary Versioneer configuration. You need +a section like: + + [versioneer] + VCS = git + style = pep440 + versionfile_source = src/myproject/_version.py + versionfile_build = myproject/_version.py + tag_prefix = + parentdir_prefix = myproject- + +You will also need to edit your setup.py to use the results: + + import versioneer + setup(version=versioneer.get_version(), + cmdclass=versioneer.get_cmdclass(), ...) + +Please read the docstring in ./versioneer.py for configuration instructions, +edit setup.cfg, and re-run the installer or 'python versioneer.py setup'. +""" + +SAMPLE_CONFIG = """ +# See the docstring in versioneer.py for instructions. Note that you must +# re-run 'versioneer.py setup' after changing this section, and commit the +# resulting files. + +[versioneer] +#VCS = git +#style = pep440 +#versionfile_source = +#versionfile_build = +#tag_prefix = +#parentdir_prefix = + +""" + +INIT_PY_SNIPPET = """ +from ._version import get_versions +__version__ = get_versions()['version'] +del get_versions +""" + + +def do_setup(): + """Main VCS-independent setup function for installing Versioneer.""" + root = get_root() + try: + cfg = get_config_from_root(root) + except (EnvironmentError, configparser.NoSectionError, + configparser.NoOptionError) as e: + if isinstance(e, (EnvironmentError, configparser.NoSectionError)): + print("Adding sample versioneer config to setup.cfg", + file=sys.stderr) + with open(os.path.join(root, "setup.cfg"), "a") as f: + f.write(SAMPLE_CONFIG) + print(CONFIG_ERROR, file=sys.stderr) + return 1 + + print(" creating %s" % cfg.versionfile_source) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + + ipy = os.path.join(os.path.dirname(cfg.versionfile_source), + "__init__.py") + if os.path.exists(ipy): + try: + with open(ipy, "r") as f: + old = f.read() + except EnvironmentError: + old = "" + if INIT_PY_SNIPPET not in old: + print(" appending to %s" % ipy) + with open(ipy, "a") as f: + f.write(INIT_PY_SNIPPET) + else: + print(" %s unmodified" % ipy) + else: + print(" %s doesn't exist, ok" % ipy) + ipy = None + + # Make sure both the top-level "versioneer.py" and versionfile_source + # (PKG/_version.py, used by runtime code) are in MANIFEST.in, so + # they'll be copied into source distributions. Pip won't be able to + # install the package without this. + manifest_in = os.path.join(root, "MANIFEST.in") + simple_includes = set() + try: + with open(manifest_in, "r") as f: + for line in f: + if line.startswith("include "): + for include in line.split()[1:]: + simple_includes.add(include) + except EnvironmentError: + pass + # That doesn't cover everything MANIFEST.in can do + # (http://docs.python.org/2/distutils/sourcedist.html#commands), so + # it might give some false negatives. Appending redundant 'include' + # lines is safe, though. + if "versioneer.py" not in simple_includes: + print(" appending 'versioneer.py' to MANIFEST.in") + with open(manifest_in, "a") as f: + f.write("include versioneer.py\n") + else: + print(" 'versioneer.py' already in MANIFEST.in") + if cfg.versionfile_source not in simple_includes: + print(" appending versionfile_source ('%s') to MANIFEST.in" % + cfg.versionfile_source) + with open(manifest_in, "a") as f: + f.write("include %s\n" % cfg.versionfile_source) + else: + print(" versionfile_source already in MANIFEST.in") + + # Make VCS-specific changes. For git, this means creating/changing + # .gitattributes to mark _version.py for export-subst keyword + # substitution. + do_vcs_install(manifest_in, cfg.versionfile_source, ipy) + return 0 + + +def scan_setup_py(): + """Validate the contents of setup.py against Versioneer's expectations.""" + found = set() + setters = False + errors = 0 + with open("setup.py", "r") as f: + for line in f.readlines(): + if "import versioneer" in line: + found.add("import") + if "versioneer.get_cmdclass()" in line: + found.add("cmdclass") + if "versioneer.get_version()" in line: + found.add("get_version") + if "versioneer.VCS" in line: + setters = True + if "versioneer.versionfile_source" in line: + setters = True + if len(found) != 3: + print("") + print("Your setup.py appears to be missing some important items") + print("(but I might be wrong). Please make sure it has something") + print("roughly like the following:") + print("") + print(" import versioneer") + print(" setup( version=versioneer.get_version(),") + print(" cmdclass=versioneer.get_cmdclass(), ...)") + print("") + errors += 1 + if setters: + print("You should remove lines like 'versioneer.VCS = ' and") + print("'versioneer.versionfile_source = ' . This configuration") + print("now lives in setup.cfg, and should be removed from setup.py") + print("") + errors += 1 + return errors + + +if __name__ == "__main__": + cmd = sys.argv[1] + if cmd == "setup": + errors = do_setup() + errors += scan_setup_py() + if errors: + sys.exit(1)