Repository: gpuopenanalytics/pynvml (language: python)

Issue:
Comparison with other Python NVML bindings
Have noticed there are a few other implementations of Python NVML bindings. It seems worthwhile to compare these to see what they offer and how they differ (particularly from what is here).

* [pynvml]( https://github.com/lukeyeager/pynvml )
* [nvidia-ml-py3]( https://github.com/nicolargo/nvidia-ml-py3 )
* [py3nvml]( https://github.com/fbcotter/py3nvml )
* [nvidia-ml-py]( https://github.com/jonsafari/nvidia-ml-py )


Discussion / hints:
Copying the authors of these other implementations in case they have thoughts on what was missing in the original package and what could be improved, @lukeyeager @nicolargo @fbcotter @jonsafari.
Not a lot was wrong or missing with the [original](https://pypi.org/project/nvidia-ml-py/), for me it was mainly:

- It was wildly out of date with the current c version of [nvml](https://github.com/NVIDIA/nvidia-settings/blob/master/src/nvml.h)
- It didn't support python3
- It looks like it was automatically generated so there was no docstrings or help for any of the underlying functions.

Most of the work I've done on py3nvml has been addressing these issues and adding in some extra utility functions that I've found useful, but could easily be moved to another library. 

Keeping up to date with nvml is hard, for example there was another release 5 days ago - [418.56](https://github.com/NVIDIA/nvidia-settings/releases/tag/418.56) which already makes py3nvml slightly behind.
Hi Fergal,

Agreed the nvml bindings are out of data.  This was an outstanding action (and a large task) to upgrade the code.

I did review the py3nvml, the added docstrings to the nvml functions are nice.   Where these descriptions of parameters, enumeration, return codes and functions sourced from the online documentation?

Ken Hester | NVIDIA Solutions Architect
c: 832-216-8736
khester@nvidia.com<mailto:khester@nvidia.com>

From: Fergal Cotter <notifications@github.com>
Sent: Monday, March 25, 2019 12:20 PM
To: gpuopenanalytics/pynvml <pynvml@noreply.github.com>
Cc: Subscribed <subscribed@noreply.github.com>
Subject: Re: [gpuopenanalytics/pynvml] Comparison with other Python NVML bindings (#2)


Not a lot was wrong or missing with the original<https://pypi.org/project/nvidia-ml-py/>, for me it was mainly:

  *   It was wildly out of date with the current c version of nvml<https://github.com/NVIDIA/nvidia-settings/blob/master/src/nvml.h>
  *   It didn't support python3
  *   It looks like it was automatically generated so there was no docstrings or help for any of the underlying functions.

Most of the work I've done on py3nvml has been addressing these issues and adding in some extra utility functions that I've found useful, but could easily be moved to another library.

Keeping up to date with nvml is hard, for example there was another release 5 days ago - 418.56<https://github.com/NVIDIA/nvidia-settings/releases/tag/418.56> which already makes py3nvml slightly behind.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub<https://github.com/gpuopenanalytics/pynvml/issues/2#issuecomment-476296864>, or mute the thread<https://github.com/notifications/unsubscribe-auth/ASakVX_A4jimercNmxcG-m7y5ZzruRmxks5vaQU2gaJpZM4cEqeQ>.

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

Hi Ken,

The descriptions and dosctrings were taken from the latest nvml header file https://github.com/NVIDIA/nvidia-settings/blob/master/src/nvml.h. I've just copied them over for each function as a guide. 

They are sadly not only in a non-pythonic shape, but incorrect. The python functions return the result and raise exceptions, whereas the docstring implies you need to pass the destination for the result as a parameter and interrogate the return value for errors.

They look like they've been formatted to automatically generate nice documentation on NVIDIA developer zone, I'd hoped to change them a little so that they would work with sphinx and we could get readthedocs style documentation for the functions, but I couldn't see an easy way to do this without painstakingly reformatting them by hand.
Looks to me like all the other repos listed start with the old "official" python2-compliant bindings from NVIDIA and update them.

In my repo (https://github.com/lukeyeager/pynvml), I started from scratch. I mostly just wanted to show off how cool pybind11 is. The amount of code is super tiny ([see here](https://github.com/lukeyeager/pynvml/blob/v0.0.1/src/main.cpp#L22-L57)), but the number of supported functions is super low.
That's pretty cool.  I think it'd be great for a more modern Python binding around nvml to exist.

@lukeyeager do you have any intentions on continuing your work?

Personally as more of an end-user, I'm more excited about seeing functionality built on top of pynvml (like dashboards) than in the underlying wrapping technology.  I'm personally inclined to build off of what's here (as archaic as it may be) until something nicer exists.  If something nicer *did* exist (*nudges @lukeyeager) that'd be swell :) 
@mrocklin not right now, no. But you basically only need to go through the nvml header and add the rest of the APIs (IIRC). Have at it, if you like!
It looks like NVIDIA has also updated their bindings on PyPi `nvidia-ml-py` to version `10.418.84` in 2019 https://pypi.org/project/nvidia-ml-py/#history. `pip install nvidia-ml-py` will still give a weird `nvidia-ml-py-375.53.tar.gz` version that I can nowhere find on PyPi but `pip install nvidia-ml-py==10.418.84` does the trick for me. That version looks like it's working with Python 3 too.

I am guessing that this is the best choice to use now?
We’ve been updating and using `pynvml`. It’s used in JupyterLab dashboards and Dask clusters.

Mostly this conversation was spurred out of an interest in figuring out what role this library plays in this space. As well as trying to figure out how best to support the community with it.

Fix patch:
diff --git a/LICENSE.txt b/LICENSE.txt
index 4012780..cd2e942 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2020, NVIDIA Corporation.
+Copyright (c) 2011-2021, NVIDIA Corporation.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
index ae50db8..af690c2 100755
--- a/README.md
+++ b/README.md
@@ -47,6 +47,12 @@ 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.
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 0000000..4ffda86
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,39 @@
+##############################################################
+# This Dockerfile contains the additional NVIDIA compilers, 
+# libraries, and plugins to enable OpenACC and NVIDIA GPU 
+# acceleration of Devito codes.
+#
+# BUILD: docker build --network=host --file docker/Dockerfile --tag pynvml .
+# RUN: docker run --gpus all --rm -it -p 8888:8888 -p 8787:8787 -p 8786:8786 pynvml
+##############################################################
+FROM python:3.6
+
+ENV DEBIAN_FRONTEND noninteractive 
+
+ADD ./requirements.txt /app/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade pip && \
+    pip install --no-cache-dir -r /app/requirements.txt && \
+    rm -rf ~/.cache/pip
+
+ADD ./pynvml /app/pynvml
+ADD ./setup.py /app/
+ADD ./setup.cfg /app/
+ADD ./README.md /app/
+ADD ./PKG-INFO /app/
+ADD ./MANIFEST.in /app/
+ADD ./help_query_gpu.txt /app/
+ADD docker/entrypoint.sh /docker-entrypoint.sh
+
+RUN chmod +x  /docker-entrypoint.sh 
+
+## Create App user 
+# Set the home directory to our app user's home.
+ENV HOME=/app
+ENV APP_HOME=/app
+
+WORKDIR /app
+
+EXPOSE 8888
+ENTRYPOINT ["/docker-entrypoint.sh"]
+CMD ["bash"]
diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh
new file mode 100644
index 0000000..71c4ed9
--- /dev/null
+++ b/docker/entrypoint.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+find /app -type f -name '*.pyc' -delete
+
+export PATH=/venv/bin:$PATH
+export PYTHONPATH=$PYTHONPATH:/app
+
+exec "$@"
diff --git a/help_query_gpu.txt b/help_query_gpu.txt
old mode 100755
new mode 100644
index d406255..75ddd88
--- a/help_query_gpu.txt
+++ b/help_query_gpu.txt
@@ -107,7 +107,7 @@ The GOM currently in use.
 The GOM that will be used on the next reboot.
 
 "fan.speed" or NVSMI_FAN_SPEED
-The fan speed value is the percent of maximum speed that the device's fan is currently intended to run at. It ranges from 0 to 100 %. Note: The reported speed is the intended fan speed. If the fan is physically blocked and unable to spin, this output will not match the actual fan speed. Many parts do not report fan speeds because they rely on cooling via fans in the surrounding enclosure.
+The fan speed value is the percent of the product's maximum noise tolerance fan speed that the device's fan is currently intended to run at. This value may exceed 100% in certain cases. Note: The reported speed is the intended fan speed. If the fan is physically blocked and unable to spin, this output will not match the actual fan speed. Many parts do not report fan speeds because they rely on cooling via fans in the surrounding enclosure.
 
 "pstate" or NVSMI_PSTATE
 The current performance state for the GPU. States range from P0 (maximum performance) to P12 (minimum performance).
@@ -210,6 +210,9 @@ NVIDIA GPUs can provide error counts for various types of ECC errors. Some ECC e
 "ecc.errors.corrected.volatile.device_memory" or NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DEV_MEM
 Errors detected in global device memory.
 
+"ecc.errors.corrected.volatile.dram" or NVSMI_ECC_ERROR_CORRECTED_VOLATILE_DRAM
+Errors detected in global device memory.
+
 "ecc.errors.corrected.volatile.register_file" or NVSMI_ECC_ERROR_CORRECTED_VOLATILE_REGFILE
 Errors detected in register file memory.
 
@@ -222,12 +225,21 @@ Errors detected in the L2 cache.
 "ecc.errors.corrected.volatile.texture_memory" or NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TEXTURE
 Parity errors detected in texture memory.
 
+"ecc.errors.corrected.volatile.cbu" or NVSMI_ECC_ERROR_CORRECTED_VOLATILE_CBU
+Parity errors detected in CBU.
+
+"ecc.errors.corrected.volatile.sram" or NVSMI_ECC_ERROR_CORRECTED_VOLATILE_SRAM
+Errors detected in global SRAMs.
+
 "ecc.errors.corrected.volatile.total" or NVSMI_ECC_ERROR_CORRECTED_VOLATILE_TOTAL
-Total errors detected across entire chip. Sum of device_memory, register_file, l1_cache, l2_cache and texture_memory.
+Total errors detected across entire chip.
 
 "ecc.errors.corrected.aggregate.device_memory" or NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DEV_MEM
 Errors detected in global device memory.
 
+"ecc.errors.corrected.aggregate.dram" or NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_DRAM
+Errors detected in global device memory.
+
 "ecc.errors.corrected.aggregate.register_file" or NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_REGFILE
 Errors detected in register file memory.
 
@@ -240,12 +252,21 @@ Errors detected in the L2 cache.
 "ecc.errors.corrected.aggregate.texture_memory" or NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TEXTURE
 Parity errors detected in texture memory.
 
+"ecc.errors.corrected.aggregate.cbu" or NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_CBU
+Parity errors detected in CBU.
+
+"ecc.errors.corrected.aggregate.sram" or NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_SRAM
+Errors detected in global SRAMs.
+
 "ecc.errors.corrected.aggregate.total" or NVSMI_ECC_ERROR_CORRECTED_AGGREGATE_TOTAL
 Total errors detected across entire chip. Sum of device_memory, register_file, l1_cache, l2_cache and texture_memory.
 
 "ecc.errors.uncorrected.volatile.device_memory" or NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_DEV_MEM
 Errors detected in global device memory.
 
+"ecc.errors.uncorrected.volatile.dram" or NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_DRAM
+Errors detected in global device memory.
+
 "ecc.errors.uncorrected.volatile.register_file" or NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_REGFILE
 Errors detected in register file memory.
 
@@ -258,12 +279,21 @@ Errors detected in the L2 cache.
 "ecc.errors.uncorrected.volatile.texture_memory" or NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_TEXTURE
 Parity errors detected in texture memory.
 
+"ecc.errors.uncorrected.volatile.cbu" or NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_CBU
+Parity errors detected in CBU.
+
+"ecc.errors.uncorrected.volatile.sram" or NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_SRAM
+Errors detected in global SRAMs.
+
 "ecc.errors.uncorrected.volatile.total" or NVSMI_ECC_ERROR_UNCORRECTED_VOLATILE_TOTAL
-Total errors detected across entire chip. Sum of device_memory, register_file, l1_cache, l2_cache and texture_memory.
+Total errors detected across entire chip. 
 
 "ecc.errors.uncorrected.aggregate.device_memory" or NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_DEV_MEM
 Errors detected in global device memory.
 
+"ecc.errors.uncorrected.aggregate.dram"  or NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_DRAM
+Errors detected in global device memory.
+
 "ecc.errors.uncorrected.aggregate.register_file" or NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_REGFILE
 Errors detected in register file memory.
 
@@ -276,8 +306,14 @@ Errors detected in the L2 cache.
 "ecc.errors.uncorrected.aggregate.texture_memory" or NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_TEXTURE
 Parity errors detected in texture memory.
 
+"ecc.errors.uncorrected.aggregate.cbu" or NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_CBU
+Parity errors detected in CBU.
+
+"ecc.errors.uncorrected.aggregate.sram" or NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_SRAM
+Errors detected in global SRAMs.
+
 "ecc.errors.uncorrected.aggregate.total" or NVSMI_ECC_ERROR_UNCORRECTED_AGGREGATE_TOTAL
-Total errors detected across entire chip. Sum of device_memory, register_file, l1_cache, l2_cache and texture_memory.
+Total errors detected across entire chip. 
 
 Section about retired_pages properties
 NVIDIA GPUs can retire pages of GPU device memory when they become unreliable. This can happen when multiple single bit ECC errors occur for the same page, or on a double bit ECC error. When a page is retired, the NVIDIA driver will hide it such that no driver, or application memory allocations can access it.
@@ -360,6 +396,17 @@ Maximum frequency of SM (Streaming Multiprocessor) clock.
 "clocks.max.memory" or "clocks.max.mem" or NVSMI_CLOCKS_MEMORY_MAX
 Maximum frequency of memory clock.
 
+Section about mig.mode properties
+A flag that indicates whether MIG mode is enabled. May be either "Enabled" or "Disabled". Changes to MIG mode require a GPU reset.
+
+"mig.mode.current" or NVSMI_MIG_MODE_CURRENT
+The MIG mode that the GPU is currently operating under.
+
+"mig.mode.pending" or NVSMI_MIG_MODE_PENDING
+The MIG mode that the GPU will operate under after reset.
+
+Section about commands to return additional properties
+
 "supported-clocks" or NVSMI_CLOCKS_SUPPORTED
 List of supported clocks.
 
diff --git a/pynvml/nvml.py b/pynvml/nvml.py
old mode 100755
new mode 100644
index 96db3c9..c356f13
--- a/pynvml/nvml.py
+++ b/pynvml/nvml.py
@@ -1,5 +1,5 @@
 # ============================================================================ #
-# Copyright (c) 2011-2015, NVIDIA Corporation.  All rights reserved.
+# 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:
@@ -26,10 +26,9 @@
 # THE POSSIBILITY OF SUCH DAMAGE.
 # ============================================================================ #
 
-"""
-Python bindings for the NVML library.
-"""
-
+##
+# Python bindings for the NVML library
+##
 from ctypes import *
 from ctypes.util import find_library
 import sys
@@ -39,28 +38,184 @@
 
 ## ========================================================================== ##
 ##                                                                            ##
-##                              CType Mappings                                ##
+##                              C Type mappings                               ##
+##                                   Enums                                    ##
 ##                                                                            ##
 ## ========================================================================== ##
 
+## C Type mappings ##
+## Enums
+NVML_API_VERSION = 11
+NVML_API_VERSION_STR = "11"
+
 ## Enums
+_nvmlBridgeChipType_t = c_uint
+NVML_BRIDGE_CHIP_PLX = 0
+NVML_BRIDGE_CHIP_BRO4 = 1
+NVML_MAX_PHYSICAL_BRIDGE = 128
+
+NVML_VALUE_NOT_AVAILABLE_ulonglong = c_ulonglong(-1)
+NVML_VALUE_NOT_AVAILABLE_uint = c_uint(-1)
+
+# Added CUDA 10.0
+NVML_DEVICE_PCI_BUS_ID_LEGACY_FMT   = "%04X:%02X:%02X.0"
+NVML_DEVICE_PCI_BUS_ID_FMT          = "%08X:%02X:%02X.0"
+
+# Updated from 6 to 12 in CUDA 11.0
+NVML_NVLINK_MAX_LINKS = 12
+# For backwards compatibility, maintain the incorrectly-named "LANES" define
+NVML_NVLINK_MAX_LANES = NVML_NVLINK_MAX_LINKS
+
+_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
+
+_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
+
+_nvmlNvLinkUtilizationControl_t = c_int
+
+_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
+
+_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
+
+# Added CUDA 9.0
+_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
+
+# Added CUDA 9.0
+_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
+
+_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
+
+_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
+
 _nvmlEnableState_t = c_uint
 NVML_FEATURE_DISABLED    = 0
 NVML_FEATURE_ENABLED     = 1
 
+# C preprocessor defined values
+nvmlFlagDefault = 0
+nvmlFlagForce = 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
-NVML_BRAND_GEFORCE = 5
-NVML_BRAND_COUNT   = 6
+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_VGAMING = 11  # NVIDIA vGaming
+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_COUNT = 1
+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
@@ -68,7 +223,7 @@
 
 _nvmlComputeMode_t = c_uint
 NVML_COMPUTEMODE_DEFAULT           = 0
-NVML_COMPUTEMODE_EXCLUSIVE_THREAD  = 1
+NVML_COMPUTEMODE_EXCLUSIVE_THREAD  = 1  ## Support Removed
 NVML_COMPUTEMODE_PROHIBITED        = 2
 NVML_COMPUTEMODE_EXCLUSIVE_PROCESS = 3
 NVML_COMPUTEMODE_COUNT             = 4
@@ -77,9 +232,13 @@
 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_COUNT = 5
+NVML_MEMORY_LOCATION_TEXTURE_SHM = 5
+NVML_MEMORY_LOCATION_CBU = 6
+NVML_MEMORY_LOCATION_SRAM = 7
+NVML_MEMORY_LOCATION_COUNT = 8
 
 # These are deprecated, instead use _nvmlMemoryErrorType_t
 _nvmlEccBitType_t = c_uint
@@ -101,7 +260,15 @@
 NVML_CLOCK_GRAPHICS  = 0
 NVML_CLOCK_SM        = 1
 NVML_CLOCK_MEM       = 2
-NVML_CLOCK_COUNT     = 3
+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
@@ -126,6 +293,11 @@
 NVML_PSTATE_15              = 15
 NVML_PSTATE_UNKNOWN         = 32
 
+_nvmlGpuOperationMode_t = c_uint
+NVML_GOM_ALL_ON                 = 0
+NVML_GOM_COMPUTE                = 1
+NVML_GOM_LOW_DP                 = 2
+
 _nvmlInforomObject_t = c_uint
 NVML_INFOROM_OEM            = 0
 NVML_INFOROM_ECC            = 1
@@ -133,43 +305,49 @@
 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_UNKNOWN             = 999
-
-_nvmlFanState_t = c_uint
-NVML_FAN_NORMAL             = 0
-NVML_FAN_FAILED             = 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
+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_UNKNOWN                  = 999
+
+# CUDA 9.0
+_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_REGISTER_FILE = 3
+NVML_MEMORY_LOCATION_TEXTURE_MEMORY = 4
+NVML_MEMORY_LOCATION_TEXTURE_SHM = 5
+NVML_MEMORY_LOCATION_CBU = 6
+# CUDA 10.0
+NVML_MEMORY_LOCATION_SRAM = 7
+NVML_MEMORY_LOCATION_COUNT = 8
 
 _nvmlPageRetirementCause_t = c_uint
-NVML_PAGE_RETIREMENT_CAUSE_DOUBLE_BIT_ECC_ERROR           = 0
-NVML_PAGE_RETIREMENT_CAUSE_MULTIPLE_SINGLE_BIT_ECC_ERRORS = 1
+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
@@ -177,101 +355,405 @@
 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_COUNT = 4
-
-_nvmlPerfPolicyType_t = c_uint
-NVML_PERF_POLICY_POWER = 0
-NVML_PERF_POLICY_THERMAL = 1
-NVML_PERF_POLICY_COUNT = 2
-
-_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_CPU = 40
-NVML_TOPOLOGY_SYSTEM = 50
-
-_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
-
-_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_COUNT = 4
-
-_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
+## Enums needed for the method nvmlDeviceGetVirtualizationMode and nvmlDeviceSetVirtualizationMode
+_nvmlGpuVirtualizationMode_t = c_uint
+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
+
+
+# Added CUDA 9.0
+_nvmlHostVgpuMode_t = c_uint
+NVML_HOST_VGPU_MODE_NON_SRIOV   = 0
+NVML_HOST_VGPU_MODE_SRIOV       = 1
+
+# Added CUDA 9.0
+## 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
+
+# Added CUDA 9.0
+_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
+
+_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
+
+# Added CUDA 11.0
+_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_UNKNOWN  = 0xffffffff
+
+_nvmlClockLimitId_t = c_uint
+NVML_CLOCK_LIMIT_ID_RANGE_START = 0xffffff00
+NVML_CLOCK_LIMIT_ID_TDP         = 0xffffff01
+NVML_CLOCK_LIMIT_ID_UNLIMITED   = 0xffffff02
+
+# Added CUDA 9.0
+'''
+ Field Identifiers.
+
+ All Identifiers pertain to a device. Each ID is only used once and is guaranteed never to change.
+'''
+_nvmlFieldValueEnums_t = c_uint
+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_MAX = 161 # One greater than the largest field ID defined above
 
-_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_COUNT = 3
-
-_nvmlNvLinkUtilizationControl_t = c_int
+_nvmlFanState_t = c_uint
+NVML_FAN_NORMAL = 0
+NVML_FAN_FAILED = 1
 
-# C preprocessor defined values
-nvmlFlagDefault             = 0
-nvmlFlagForce               = 1
+_nvmlLedColor_t = c_uint
+NVML_LED_COLOR_GREEN = 0
+NVML_LED_COLOR_AMBER = 1
+
+# Added CUDA 9.0
+NVML_GRID_LICENSE_BUFFER_SIZE = 128
+NVML_VGPU_NAME_BUFFER_SIZE = 64
+NVML_GRID_LICENSE_FEATURE_MAX_COUNT = 3
+
+# Added CUDA 9.0
+NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION = 0
+NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION_NO = 0
+NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION_YES = 1
+
+# Added CUDA 10.2
+NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION = 0
+NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION_NO = 0
+NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION_YES = 1
+
+# Added CUDA 9.0
+_nvmlEncoderQueryType_t = c_uint
+_nvmlEncoderType_t = c_uint
+NVML_ENCODER_QUERY_H264 = 0
+NVML_ENCODER_QUERY_HEVC = 1
+
+# Added CUDA 10.0
+_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
+
+# Added CUDA 10.0
+_nvmlFBCStats_t = c_uint
+NVML_NVFBC_SESSION_FLAG_DIFFMAP_ENABLED = 1
+NVML_NVFBC_SESSION_FLAG_CLASSIFICATIONMAP_ENABLED = 2
+NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_NO_WAIT = 4
+NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_INFINITE = 8
+NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_TIMEOUT = 16
+
+# Added CUDA 9.2
+_nvmlDetachGpuState_t = c_uint
+NVML_DETACH_GPU_KEEP = 0
+NVML_DETACH_GPU_REMOVE = 1
+
+# Added CUDA 9.2
+_nvmlPcieLinkState_t = c_uint
+NVML_PCIE_LINK_KEEP = 0
+NVML_PCIE_LINK_SHUT_DOWN = 1
+
+# Added CUDA 9.1
+_nvmlInitializationAndCleanup_t = c_uint
+NVML_INIT_FLAG_NO_GPUS   = 1
+# Added CUDA 9.2
+NVML_INIT_FLAG_NO_ATTACH = 2
 
 # buffer size
+_nvmlConstants_t = c_uint
+NVML_MAX_GPC_COUNT                           = 32
 NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE      = 16
 NVML_DEVICE_UUID_BUFFER_SIZE                 = 80
-NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE       = 81
+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_SERIAL_BUFFER_SIZE               = 30
+NVML_DEVICE_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
+
+_nvmlAffinityScope_t = c_uint
+NVML_AFFINITY_SCOPE_NODE   = 0
+NVML_AFFINITY_SCOPE_SOCKET = 1
+
+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_COUNT        = 0x8
+
+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_COUNT   = 0x7
+
+NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_SHARED = 0x0
+NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT = 0x1
 
-# NvLink
-NVML_NVLINK_MAX_LINKS = 6
-
-NVML_VALUE_NOT_AVAILABLE_ulonglong = c_ulonglong(-1)
-NVML_VALUE_NOT_AVAILABLE_uint = c_uint(-1)
 
 ## ========================================================================== ##
 ##                                                                            ##
@@ -279,10 +761,10 @@
 ##                                                                            ##
 ## ========================================================================== ##
 
-nvml_lib = None
-lib_load_lock = threading.Lock()
-nvml_lib_refcount = 0 # Incremented on each nvmlInit and decremented on nvmlShutdown
-
+## Lib loading ##
+nvmlLib = None
+libLoadLock = threading.Lock()
+_nvmlLib_refcount = 0 # Incremented on each nvmlInit and decremented on nvmlShutdown
 
 ## ========================================================================== ##
 ##                                                                            ##
@@ -291,7 +773,7 @@
 ## ========================================================================== ##
 
 class NVMLError(Exception):
-    _val_mapping = dict()
+    _valClassMapping = dict()
     # List of currently known error codes
     _errcode_to_string = {
         NVML_ERROR_UNINITIALIZED:       "Uninitialized",
@@ -312,29 +794,37 @@ class NVMLError(Exception):
         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 _extract_errors_as_classes function for more details
+        See _extractNVMLErrorsAsClasses function for more details
         '''
         if typ == NVMLError:
-            typ = NVMLError._val_mapping.get(value, typ)
+            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(nvml_error_string(self.value))
+                NVMLError._errcode_to_string[self.value] = str(nvmlErrorString(self.value))
             return NVMLError._errcode_to_string[self.value]
-        except NVMLError_Uninitialized:
+        except NVMLError:
             return "NVML Error with code %d" % self.value
+    
     def __eq__(self, other):
         return self.value == other.value
 
-def _extract_errors_as_classes():
+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.
 
@@ -345,7 +835,7 @@ def _extract_errors_as_classes():
     e.g. NVML_ERROR_ALREADY_INITIALIZED will be turned into NVMLError_AlreadyInitialized
     '''
     this_module = sys.modules[__name__]
-    nvmlErrorsNames = filter(lambda x: x.startswith("NVML_ERROR_"), dir(this_module))
+    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("_", "")
@@ -358,10 +848,12 @@ def new(typ):
         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._val_mapping[err_val] = new_error_class
-_extract_errors_as_classes()
+        NVMLError._valClassMapping[err_val] = new_error_class
+
+_extractNVMLErrorsAsClasses()
 
-def check_return(ret):
+
+def _nvmlCheckReturn(ret):
     if (ret != NVML_SUCCESS):
         raise NVMLError(ret)
     return ret
@@ -373,61 +865,65 @@ def check_return(ret):
 ##                                                                            ##
 ## ========================================================================== ##
 
-_func_pointer_cache = dict() # function pointers are cached to prevent unnecessary lib_load_lock locking
-def get_func_pointer(name):
-    global nvml_lib
+_nvmlGetFunctionPointer_cache = dict()  # function pointers are cached to prevent unnecessary libLoadLock locking
+
 
-    if name in _func_pointer_cache:
-        return _func_pointer_cache[name]
+def _nvmlGetFunctionPointer(name):
+    global nvmlLib
 
-    lib_load_lock.acquire()
+    if name in _nvmlGetFunctionPointer_cache:
+        return _nvmlGetFunctionPointer_cache[name]
+
+    libLoadLock.acquire()
     try:
         # ensure library was loaded
-        if (nvml_lib == None):
+        if (nvmlLib == None):
             raise NVMLError(NVML_ERROR_UNINITIALIZED)
         try:
-            _func_pointer_cache[name] = getattr(nvml_lib, name)
-            return _func_pointer_cache[name]
+            _nvmlGetFunctionPointer_cache[name] = getattr(nvmlLib, name)
+            return _nvmlGetFunctionPointer_cache[name]
         except AttributeError:
             raise NVMLError(NVML_ERROR_FUNCTION_NOT_FOUND)
     finally:
         # lock is always freed
-        lib_load_lock.release()
+        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 FriendlyObject(object):
+class nvmlFriendlyObject(object):
     def __init__(self, dictionary):
         for x in dictionary:
             setattr(self, x, dictionary[x])
     def __str__(self):
         return self.__dict__.__str__()
 
-def struct_to_friendly_object(struct):
+def nvmlStructToFriendlyObject(struct):
     d = {}
     for x in struct._fields_:
         key = x[0]
         value = getattr(struct, key)
         d[key] = value
-    obj = FriendlyObject(d)
+    obj = nvmlFriendlyObject(d)
     return obj
 
 # pack the object so it can be passed to the NVML library
-def friendly_object_to_struct(obj, model):
+def nvmlFriendlyObjectToStruct(obj, model):
     for x in model._fields_:
         key = x[0]
         value = obj.__dict__[key]
         setattr(model, key, value)
     return model
 
+
 ## Unit structures
 class struct_c_nvmlUnit_t(Structure):
-    pass # opaque handle
+    pass  # opaque handle
 c_nvmlUnit_t = POINTER(struct_c_nvmlUnit_t)
 
-class PrintableStructure(Structure):
+class _PrintableStructure(Structure):
     """
     Abstract class that produces nicer __str__ output than ctypes.Structure.
     e.g. instead of:
@@ -458,7 +954,7 @@ def __str__(self):
             elif "<default>" in self._fmt_:
                 fmt = self._fmt_["<default>"]
             result.append(("%s: " + fmt) % (key, value))
-        return self.__class__.__name__ + "(" + string.join(result, ", ") + ")"
+        return self.__class__.__name__ + "(" +  ", ".join(result) + ")"
 
 
 ## ========================================================================== ##
@@ -467,7 +963,7 @@ def __str__(self):
 ##                                                                            ##
 ## ========================================================================== ##
 
-class c_nvmlUnitInfo_t(PrintableStructure):
+class c_nvmlUnitInfo_t(_PrintableStructure):
     _fields_ = [
         ('name', c_char * 96),
         ('id', c_char * 96),
@@ -475,13 +971,13 @@ class c_nvmlUnitInfo_t(PrintableStructure):
         ('firmwareVersion', c_char * 96),
     ]
 
-class c_nvmlLedState_t(PrintableStructure):
+class c_nvmlLedState_t(_PrintableStructure):
     _fields_ = [
         ('cause', c_char * 256),
         ('color', _nvmlLedColor_t),
     ]
 
-class c_nvmlPSUInfo_t(PrintableStructure):
+class c_nvmlPSUInfo_t(_PrintableStructure):
     _fields_ = [
         ('state', c_char * 256),
         ('current', c_uint),
@@ -489,13 +985,13 @@ class c_nvmlPSUInfo_t(PrintableStructure):
         ('power', c_uint),
     ]
 
-class c_nvmlUnitFanInfo_t(PrintableStructure):
+class c_nvmlUnitFanInfo_t(_PrintableStructure):
     _fields_ = [
         ('speed', c_uint),
         ('state', _nvmlFanState_t),
     ]
 
-class c_nvmlUnitFanSpeeds_t(PrintableStructure):
+class c_nvmlUnitFanSpeeds_t(_PrintableStructure):
     _fields_ = [
         ('fans', c_nvmlUnitFanInfo_t * 24),
         ('count', c_uint)
@@ -506,9 +1002,10 @@ class struct_c_nvmlDevice_t(Structure):
     pass # opaque handle
 c_nvmlDevice_t = POINTER(struct_c_nvmlDevice_t)
 
-class nvmlPciInfo_t(PrintableStructure):
+# Legacy pciInfo used for _v1 and _v2
+class nvmlPciInfo_v2_t(_PrintableStructure):
     _fields_ = [
-        ('busId', c_char * 16),
+        ('busId', c_char * NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE),
         ('domain', c_uint),
         ('bus', c_uint),
         ('device', c_uint),
@@ -529,7 +1026,42 @@ class nvmlPciInfo_t(PrintableStructure):
             'pciSubSystemId' : "0x%08X",
             }
 
-class c_nvmlMemory_t(PrintableStructure):
+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),
@@ -537,7 +1069,7 @@ class c_nvmlMemory_t(PrintableStructure):
     ]
     _fmt_ = {'<default>': "%d B"}
 
-class c_nvmlBAR1Memory_t(PrintableStructure):
+class c_nvmlBAR1Memory_t(_PrintableStructure):
     _fields_ = [
         ('bar1Total', c_ulonglong),
         ('bar1Free', c_ulonglong),
@@ -545,6 +1077,17 @@ class c_nvmlBAR1Memory_t(PrintableStructure):
     ]
     _fmt_ = {'<default>': "%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.
 #
@@ -553,28 +1096,31 @@ class c_nvmlBAR1Memory_t(PrintableStructure):
 #     pass
 # else:
 #    print("Using %d MiB of memory" % (info.usedGpuMemory / 1024 / 1024))
+# endif
 #
 # See NVML documentation for more information
-class c_nvmlProcessInfo_t(PrintableStructure):
+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):
+class c_nvmlBridgeChipInfo_t(_PrintableStructure):
     _fields_ = [
         ('type', _nvmlBridgeChipType_t),
         ('fwVersion', c_uint),
     ]
 
-class c_nvmlBridgeChipHierarchy_t(PrintableStructure):
+class c_nvmlBridgeChipHierarchy_t(_PrintableStructure):
     _fields_ = [
         ('bridgeCount', c_uint),
         ('bridgeChipInfo', c_nvmlBridgeChipInfo_t * 128),
     ]
 
-class c_nvmlEccErrorCounts_t(PrintableStructure):
+class c_nvmlEccErrorCounts_t(_PrintableStructure):
     _fields_ = [
         ('l1Cache', c_ulonglong),
         ('l2Cache', c_ulonglong),
@@ -582,7 +1128,7 @@ class c_nvmlEccErrorCounts_t(PrintableStructure):
         ('registerFile', c_ulonglong),
     ]
 
-class c_nvmlUtilization_t(PrintableStructure):
+class c_nvmlUtilization_t(_PrintableStructure):
     _fields_ = [
         ('gpu', c_uint),
         ('memory', c_uint),
@@ -590,7 +1136,7 @@ class c_nvmlUtilization_t(PrintableStructure):
     _fmt_ = {'<default>': "%d %%"}
 
 # Added in 2.285
-class c_nvmlHwbcEntry_t(PrintableStructure):
+class c_nvmlHwbcEntry_t(_PrintableStructure):
     _fields_ = [
         ('hwbcId', c_uint),
         ('firmwareVersion', c_char * 32),
@@ -602,68 +1148,195 @@ class c_nvmlValue_t(Union):
         ('uiVal', c_uint),
         ('ulVal', c_ulong),
         ('ullVal', c_ulonglong),
+        ('sllVal', c_longlong),
     ]
 
-class c_nvmlSample_t(PrintableStructure):
+class c_nvmlSample_t(_PrintableStructure):
     _fields_ = [
         ('timeStamp', c_ulonglong),
         ('sampleValue', c_nvmlValue_t),
     ]
 
-class c_nvmlViolationTime_t(PrintableStructure):
+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_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_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 |
-                                        nvmlEventTypeXidCriticalError
+                                        nvmlEventTypeNone
+                                        | nvmlEventTypeSingleBitEccError
+                                        | nvmlEventTypeDoubleBitEccError
+                                        | nvmlEventTypePState
+                                        | nvmlEventTypeClock
+                                        | nvmlEventTypePowerSourceChange
+                                        | nvmlEventTypeXidCriticalError
+                                        | nvmlEventMigConfigChange
                                      )
 
+class c_nvmlEventData_t(_PrintableStructure):
+    _fields_ = [
+        ('device', c_nvmlDevice_t),
+        ('eventType', c_ulonglong),
+        ('eventData', c_ulonglong),
+        # Added CUDA 11
+        ('gpuInstanceId', c_uint),
+        ('computeInstanceId', c_uint),
+    ]
+    _fmt_ = {'eventType': "0x%08X"}
+
+
 ## Clock Throttle Reasons defines
-nvmlClocksThrottleReasonGpuIdle           = 0x0000000000000001
+nvmlClocksThrottleReasonGpuIdle              = 0x0000000000000001
 nvmlClocksThrottleReasonApplicationsClocksSetting = 0x0000000000000002
 nvmlClocksThrottleReasonUserDefinedClocks         = nvmlClocksThrottleReasonApplicationsClocksSetting # deprecated, use nvmlClocksThrottleReasonApplicationsClocksSetting
-nvmlClocksThrottleReasonSwPowerCap        = 0x0000000000000004
-nvmlClocksThrottleReasonHwSlowdown        = 0x0000000000000008
-nvmlClocksThrottleReasonUnknown           = 0x8000000000000000
-nvmlClocksThrottleReasonNone              = 0x0000000000000000
-nvmlClocksThrottleReasonAll               = (
-                                               nvmlClocksThrottleReasonNone |
-                                               nvmlClocksThrottleReasonGpuIdle |
-                                               nvmlClocksThrottleReasonApplicationsClocksSetting |
-                                               nvmlClocksThrottleReasonSwPowerCap |
-                                               nvmlClocksThrottleReasonHwSlowdown |
-                                               nvmlClocksThrottleReasonUnknown
-                                            )
-
-class c_nvmlEventData_t(PrintableStructure):
+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)
+        ('eventData', c_ulonglong),
+        ('gpuInstanceId', c_uint),
+        ('computeInstanceId', c_uint)
     ]
     _fmt_ = {'eventType': "0x%08X"}
 
-class c_nvmlAccountingStats_t(PrintableStructure):
+class c_nvmlAccountingStats_t(_PrintableStructure):
     _fields_ = [
         ('gpuUtilization', c_uint),
         ('memoryUtilization', c_uint),
@@ -674,23 +1347,140 @@ class c_nvmlAccountingStats_t(PrintableStructure):
         ('reserved', c_uint * 5)
     ]
 
-class c_nvmlPciInfo_t(PrintableStructure):
+class c_nvmlVgpuVersion_t(Structure):
+    _fields_ = [("minVersion", c_uint),
+                ("maxVersion", c_uint)
+               ]
+
+class c_nvmlVgpuMetadata_t(Structure):
+    _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(Structure):
+    _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)
+               ]
+
+class c_nvmlFBCStats_t(Structure):
+    _fields_ = [("sessionsCount", c_uint),
+                ("averageFPS", c_uint),
+                ("averageLatency", c_uint)
+               ]
+
+class c_nvmlFBCSession_t(_PrintableStructure):
     _fields_ = [
-        ('bus', c_uint),
-        ('busId', c_char * 16),
-        ('busIdLegacy', c_char * 16),
-        ('device', c_uint),
-        ('domain', c_uint),
-        ('pciDeviceId', c_uint),
-        ('pciSubSystemId', c_uint)
+        ('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),
     ]
-    _fmt_ = {
-            'domain'         : "0x%04X",
-            'bus'            : "0x%02X",
-            'device'         : "0x%02X",
-            'pciDeviceId'    : "0x%08X",
-            'pciSubSystemId' : "0x%08X",
-            }
+    
+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),
+               ]
+
+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)
+
+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)
+               ]
+
+class c_nvmlComputeInstanceInfo_t(Structure):
+    _fields_ = [("device", c_nvmlDevice_t),
+                ("gpuInstance", c_nvmlGpuInstance_t),
+                ("id", c_uint),
+                ("profileId", c_uint),
+                ("placement", c_nvmlComputeInstancePlacement_t)
+               ]
+
+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)
+               ]
 
 
 ## ========================================================================== ##
@@ -699,10 +1489,45 @@ class c_nvmlPciInfo_t(PrintableStructure):
 ##                                                                            ##
 ## ========================================================================== ##
 
+def _load_nvmlLibrary():
+    """
+    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 nvmlInit():
     """Initialize NVML.
 
-    Uses nvmlInit_v2() from the underlying NVML library.
+    Uses nvmlInitWithFlags(0) from the underlying NVML library.
 
     Args:
         None
@@ -711,54 +1536,42 @@ def nvmlInit():
         None
     """
 
-    def _load_nvml_library():
-        """
-        Load the library if it isn't loaded already
-        """
-        global nvml_lib
-
-        if (nvml_lib == None):
-            # lock to ensure only one caller loads the library
-            lib_load_lock.acquire()
-
-            try:
-                # ensure the library still isn't loaded
-                if (nvml_lib == None):
-                    try:
-                        if (sys.platform[:3] == "win"):
-                            # cdecl calling convention
-                            # load nvml.dll from %ProgramFiles%/NVIDIA Corporation/NVSMI/nvml.dll
-                            nvml_lib = CDLL(os.path.join(os.getenv("ProgramFiles", "C:/Program Files"), "NVIDIA Corporation/NVSMI/nvml.dll"))
-                        else:
-                            # assume linux
-                            nvml_lib = CDLL("libnvidia-ml.so.1")
-                    except OSError as ose:
-                        check_return(NVML_ERROR_LIBRARY_NOT_FOUND)
-                    if (nvml_lib == None):
-                        check_return(NVML_ERROR_LIBRARY_NOT_FOUND)
-            finally:
-                # lock is always freed
-                lib_load_lock.release()
-    _load_nvml_library()
-
     #
     # Initialize the library
     #
-    fn = get_func_pointer("nvmlInit_v2")
-    ret = fn()
-    check_return(ret)
-
-    # Atomically update refcount
-    global nvml_lib_refcount
-    lib_load_lock.acquire()
-    nvml_lib_refcount += 1
-    lib_load_lock.release()
+    nvmlInitWithFlags(0)
     return None
 
-def nvmlShutdown():
-    """Shutdown NVML.
 
-    Uses nvmlShutdown() from the underlying NVML library.
+def nvmlInitWithFlags(flags):
+    """Initialize NVML.
+
+    Uses nvmlInitWithFlags() from the underlying NVML library.
+
+    Args:
+        flags
+
+    Returns:
+        None
+    """
+    _load_nvmlLibrary()
+
+    fn = _nvmlGetFunctionPointer("nvmlInitWithFlags")
+    ret = fn(c_uint(flags))
+    _nvmlCheckReturn(ret)
+
+    # Atomically update refcount
+    global _nvmlLib_refcount
+    libLoadLock.acquire()
+    _nvmlLib_refcount += 1
+    libLoadLock.release()
+    return None
+
+
+def nvmlShutdown():
+    """Shutdown NVML.
+
+    Uses nvmlShutdown() from the underlying NVML library.
 
     Args:
         None
@@ -769,21 +1582,22 @@ def nvmlShutdown():
     #
     # Leave the library loaded, but shutdown the interface
     #
-    fn = get_func_pointer("nvmlShutdown")
+    fn = _nvmlGetFunctionPointer("nvmlShutdown")
     ret = fn()
-    check_return(ret)
+    _nvmlCheckReturn(ret)
 
     # Atomically update refcount
-    global nvml_lib_refcount
-    lib_load_lock.acquire()
-    if (0 < nvml_lib_refcount):
-        nvml_lib_refcount -= 1
-    lib_load_lock.release()
+    global _nvmlLib_refcount
+    libLoadLock.acquire()
+    if (0 < _nvmlLib_refcount):
+        _nvmlLib_refcount -= 1
+    libLoadLock.release()
     return None
 
+
 # Added in 2.285
-def nvml_error_string(result):
-    fn = get_func_pointer("nvmlErrorString")
+def nvmlErrorString(result):
+    fn = _nvmlGetFunctionPointer("nvmlErrorString")
     fn.restype = c_char_p # otherwise return is an int
     ret = fn(result)
     return ret
@@ -791,31 +1605,45 @@ def nvml_error_string(result):
 # Added in 2.285
 def nvmlSystemGetNVMLVersion():
     c_version = create_string_buffer(NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE)
-    fn = get_func_pointer("nvmlSystemGetNVMLVersion")
+    fn = _nvmlGetFunctionPointer("nvmlSystemGetNVMLVersion")
     ret = fn(c_version, c_uint(NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE))
-    check_return(ret)
+    _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
 def nvmlSystemGetProcessName(pid):
     c_name = create_string_buffer(1024)
-    fn = get_func_pointer("nvmlSystemGetProcessName")
+    fn = _nvmlGetFunctionPointer("nvmlSystemGetProcessName")
     ret = fn(c_uint(pid), c_name, c_uint(1024))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_name.value
 
 def nvmlSystemGetDriverVersion():
     c_version = create_string_buffer(NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE)
-    fn = get_func_pointer("nvmlSystemGetDriverVersion")
+    fn = _nvmlGetFunctionPointer("nvmlSystemGetDriverVersion")
     ret = fn(c_version, c_uint(NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_version.value
 
 # Added in 2.285
 def nvmlSystemGetHicVersion():
     c_count = c_uint(0)
     hics = None
-    fn = get_func_pointer("nvmlSystemGetHicVersion")
+    fn = _nvmlGetFunctionPointer("nvmlSystemGetHicVersion")
 
     # get the count
     ret = fn(byref(c_count), None)
@@ -825,292 +1653,332 @@ def nvmlSystemGetHicVersion():
         (ret != NVML_ERROR_INSUFFICIENT_SIZE)):
         raise NVMLError(ret)
 
-    # if there are no hics
+    # 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)
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return hics
 
 ## Unit get functions
 def nvmlUnitGetCount():
     c_count = c_uint()
-    fn = get_func_pointer("nvmlUnitGetCount")
+    fn = _nvmlGetFunctionPointer("nvmlUnitGetCount")
     ret = fn(byref(c_count))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_count.value
 
 def nvmlUnitGetHandleByIndex(index):
     c_index = c_uint(index)
     unit = c_nvmlUnit_t()
-    fn = get_func_pointer("nvmlUnitGetHandleByIndex")
+    fn = _nvmlGetFunctionPointer("nvmlUnitGetHandleByIndex")
     ret = fn(c_index, byref(unit))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return unit
 
 def nvmlUnitGetUnitInfo(unit):
     c_info = c_nvmlUnitInfo_t()
-    fn = get_func_pointer("nvmlUnitGetUnitInfo")
+    fn = _nvmlGetFunctionPointer("nvmlUnitGetUnitInfo")
     ret = fn(unit, byref(c_info))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_info
 
 def nvmlUnitGetLedState(unit):
     c_state =  c_nvmlLedState_t()
-    fn = get_func_pointer("nvmlUnitGetLedState")
+    fn = _nvmlGetFunctionPointer("nvmlUnitGetLedState")
     ret = fn(unit, byref(c_state))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_state
 
 def nvmlUnitGetPsuInfo(unit):
     c_info = c_nvmlPSUInfo_t()
-    fn = get_func_pointer("nvmlUnitGetPsuInfo")
+    fn = _nvmlGetFunctionPointer("nvmlUnitGetPsuInfo")
     ret = fn(unit, byref(c_info))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_info
 
 def nvmlUnitGetTemperature(unit, type):
     c_temp = c_uint()
-    fn = get_func_pointer("nvmlUnitGetTemperature")
+    fn = _nvmlGetFunctionPointer("nvmlUnitGetTemperature")
     ret = fn(unit, c_uint(type), byref(c_temp))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_temp.value
 
 def nvmlUnitGetFanSpeedInfo(unit):
     c_speeds = c_nvmlUnitFanSpeeds_t()
-    fn = get_func_pointer("nvmlUnitGetFanSpeedInfo")
+    fn = _nvmlGetFunctionPointer("nvmlUnitGetFanSpeedInfo")
     ret = fn(unit, byref(c_speeds))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_speeds
 
 # added to API
 def nvmlUnitGetDeviceCount(unit):
     c_count = c_uint(0)
     # query the unit to determine device count
-    fn = get_func_pointer("nvmlUnitGetDevices")
+    fn = _nvmlGetFunctionPointer("nvmlUnitGetDevices")
     ret = fn(unit, byref(c_count), None)
     if (ret == NVML_ERROR_INSUFFICIENT_SIZE):
         ret = NVML_SUCCESS
-    check_return(ret)
+    _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 = get_func_pointer("nvmlUnitGetDevices")
+    fn = _nvmlGetFunctionPointer("nvmlUnitGetDevices")
     ret = fn(unit, byref(c_count), c_devices)
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_devices
 
 ## Device get functions
 def nvmlDeviceGetCount():
     c_count = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetCount_v2")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetCount_v2")
     ret = fn(byref(c_count))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_count.value
 
 def nvmlDeviceGetHandleByIndex(index):
     c_index = c_uint(index)
     device = c_nvmlDevice_t()
-    fn = get_func_pointer("nvmlDeviceGetHandleByIndex_v2")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetHandleByIndex_v2")
     ret = fn(c_index, byref(device))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return device
 
 def nvmlDeviceGetHandleBySerial(serial):
     c_serial = c_char_p(serial)
     device = c_nvmlDevice_t()
-    fn = get_func_pointer("nvmlDeviceGetHandleBySerial")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetHandleBySerial")
     ret = fn(c_serial, byref(device))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return device
 
 def nvmlDeviceGetHandleByUUID(uuid):
     c_uuid = c_char_p(uuid)
     device = c_nvmlDevice_t()
-    fn = get_func_pointer("nvmlDeviceGetHandleByUUID")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetHandleByUUID")
     ret = fn(c_uuid, byref(device))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return device
 
 def nvmlDeviceGetHandleByPciBusId(pciBusId):
     c_busId = c_char_p(pciBusId)
     device = c_nvmlDevice_t()
-    fn = get_func_pointer("nvmlDeviceGetHandleByPciBusId_v2")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetHandleByPciBusId_v2")
     ret = fn(c_busId, byref(device))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return device
 
 def nvmlDeviceGetName(handle):
     c_name = create_string_buffer(NVML_DEVICE_NAME_BUFFER_SIZE)
-    fn = get_func_pointer("nvmlDeviceGetName")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetName")
     ret = fn(handle, c_name, c_uint(NVML_DEVICE_NAME_BUFFER_SIZE))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_name.value
 
 def nvmlDeviceGetBoardId(handle):
     c_id = c_uint();
-    fn = get_func_pointer("nvmlDeviceGetBoardId")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetBoardId")
     ret = fn(handle, byref(c_id))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_id.value
 
 def nvmlDeviceGetMultiGpuBoard(handle):
     c_multiGpu = c_uint();
-    fn = get_func_pointer("nvmlDeviceGetMultiGpuBoard")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetMultiGpuBoard")
     ret = fn(handle, byref(c_multiGpu))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_multiGpu.value
 
 def nvmlDeviceGetBrand(handle):
     c_type = _nvmlBrandType_t()
-    fn = get_func_pointer("nvmlDeviceGetBrand")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetBrand")
     ret = fn(handle, byref(c_type))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_type.value
 
+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
+
 def nvmlDeviceGetSerial(handle):
     c_serial = create_string_buffer(NVML_DEVICE_SERIAL_BUFFER_SIZE)
-    fn = get_func_pointer("nvmlDeviceGetSerial")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetSerial")
     ret = fn(handle, c_serial, c_uint(NVML_DEVICE_SERIAL_BUFFER_SIZE))
-    check_return(ret)
+    _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 = get_func_pointer("nvmlDeviceGetCpuAffinity")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetCpuAffinity")
     ret = fn(handle, cpuSetSize, byref(c_affinity))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_affinity
 
 def nvmlDeviceSetCpuAffinity(handle):
-    fn = get_func_pointer("nvmlDeviceSetCpuAffinity")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetCpuAffinity")
     ret = fn(handle)
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceClearCpuAffinity(handle):
-    fn = get_func_pointer("nvmlDeviceClearCpuAffinity")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceClearCpuAffinity")
     ret = fn(handle)
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceGetMinorNumber(handle):
     c_minor_number = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetMinorNumber")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetMinorNumber")
     ret = fn(handle, byref(c_minor_number))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_minor_number.value
 
 def nvmlDeviceGetUUID(handle):
-    c_uuid = create_string_buffer(NVML_DEVICE_UUID_BUFFER_SIZE)
-    fn = get_func_pointer("nvmlDeviceGetUUID")
-    ret = fn(handle, c_uuid, c_uint(NVML_DEVICE_UUID_BUFFER_SIZE))
-    check_return(ret)
+    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
 
 def nvmlDeviceGetInforomVersion(handle, infoRomObject):
     c_version = create_string_buffer(NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE)
-    fn = get_func_pointer("nvmlDeviceGetInforomVersion")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetInforomVersion")
     ret = fn(handle, _nvmlInforomObject_t(infoRomObject),
-	         c_version, c_uint(NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE))
-    check_return(ret)
+                 c_version, c_uint(NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE))
+    _nvmlCheckReturn(ret)
     return c_version.value
 
 # Added in 4.304
 def nvmlDeviceGetInforomImageVersion(handle):
     c_version = create_string_buffer(NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE)
-    fn = get_func_pointer("nvmlDeviceGetInforomImageVersion")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetInforomImageVersion")
     ret = fn(handle, c_version, c_uint(NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_version.value
 
 # Added in 4.304
 def nvmlDeviceGetInforomConfigurationChecksum(handle):
     c_checksum = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetInforomConfigurationChecksum")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetInforomConfigurationChecksum")
     ret = fn(handle, byref(c_checksum))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_checksum.value
 
 # Added in 4.304
 def nvmlDeviceValidateInforom(handle):
-    fn = get_func_pointer("nvmlDeviceValidateInforom")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceValidateInforom")
     ret = fn(handle)
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceGetDisplayMode(handle):
     c_mode = _nvmlEnableState_t()
-    fn = get_func_pointer("nvmlDeviceGetDisplayMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetDisplayMode")
     ret = fn(handle, byref(c_mode))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_mode.value
 
 def nvmlDeviceGetDisplayActive(handle):
     c_mode = _nvmlEnableState_t()
-    fn = get_func_pointer("nvmlDeviceGetDisplayActive")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetDisplayActive")
     ret = fn(handle, byref(c_mode))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_mode.value
 
 
 def nvmlDeviceGetPersistenceMode(handle):
     c_state = _nvmlEnableState_t()
-    fn = get_func_pointer("nvmlDeviceGetPersistenceMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPersistenceMode")
     ret = fn(handle, byref(c_state))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_state.value
 
-def nvmlDeviceGetPciInfo(handle):
+def nvmlDeviceGetPciInfo_v3(handle):
     c_info = nvmlPciInfo_t()
-    fn = get_func_pointer("nvmlDeviceGetPciInfo_v2")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPciInfo_v3")
     ret = fn(handle, byref(c_info))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_info
 
+def nvmlDeviceGetPciInfo(handle):
+    return nvmlDeviceGetPciInfo_v3(handle)
+
 def nvmlDeviceGetClockInfo(handle, type):
     c_clock = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetClockInfo")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetClockInfo")
     ret = fn(handle, _nvmlClockType_t(type), byref(c_clock))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_clock.value
 
 # Added in 2.285
 def nvmlDeviceGetMaxClockInfo(handle, type):
     c_clock = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetMaxClockInfo")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetMaxClockInfo")
     ret = fn(handle, _nvmlClockType_t(type), byref(c_clock))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_clock.value
 
 # Added in 4.304
 def nvmlDeviceGetApplicationsClock(handle, type):
     c_clock = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetApplicationsClock")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetApplicationsClock")
     ret = fn(handle, _nvmlClockType_t(type), byref(c_clock))
-    check_return(ret)
+    _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 = get_func_pointer("nvmlDeviceGetDefaultApplicationsClock")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetDefaultApplicationsClock")
     ret = fn(handle, _nvmlClockType_t(type), byref(c_clock))
-    check_return(ret)
+    _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 = get_func_pointer("nvmlDeviceGetSupportedMemoryClocks")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetSupportedMemoryClocks")
     ret = fn(handle, byref(c_count), None)
 
     if (ret == NVML_SUCCESS):
@@ -1123,7 +1991,7 @@ def nvmlDeviceGetSupportedMemoryClocks(handle):
 
         # make the call again
         ret = fn(handle, byref(c_count), c_clocks)
-        check_return(ret)
+        _nvmlCheckReturn(ret)
 
         procs = []
         for i in range(c_count.value):
@@ -1138,7 +2006,7 @@ def nvmlDeviceGetSupportedMemoryClocks(handle):
 def nvmlDeviceGetSupportedGraphicsClocks(handle, memoryClockMHz):
     # first call to get the size
     c_count = c_uint(0)
-    fn = get_func_pointer("nvmlDeviceGetSupportedGraphicsClocks")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetSupportedGraphicsClocks")
     ret = fn(handle, c_uint(memoryClockMHz), byref(c_count), None)
 
     if (ret == NVML_SUCCESS):
@@ -1151,7 +2019,7 @@ def nvmlDeviceGetSupportedGraphicsClocks(handle, memoryClockMHz):
 
         # make the call again
         ret = fn(handle, c_uint(memoryClockMHz), byref(c_count), c_clocks)
-        check_return(ret)
+        _nvmlCheckReturn(ret)
 
         procs = []
         for i in range(c_count.value):
@@ -1164,101 +2032,115 @@ def nvmlDeviceGetSupportedGraphicsClocks(handle, memoryClockMHz):
 
 def nvmlDeviceGetFanSpeed(handle):
     c_speed = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetFanSpeed")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetFanSpeed")
     ret = fn(handle, byref(c_speed))
-    check_return(ret)
+    _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 nvmlDeviceGetTemperature(handle, sensor):
     c_temp = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetTemperature")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetTemperature")
     ret = fn(handle, _nvmlTemperatureSensors_t(sensor), byref(c_temp))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_temp.value
 
 def nvmlDeviceGetTemperatureThreshold(handle, threshold):
     c_temp = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetTemperatureThreshold")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetTemperatureThreshold")
     ret = fn(handle, _nvmlTemperatureThresholds_t(threshold), byref(c_temp))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_temp.value
 
+def nvmlDeviceSetTemperatureThreshold(handle, threshold):
+    c_temp = c_uint()
+    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 = get_func_pointer("nvmlDeviceGetPowerState")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerState")
     ret = fn(handle, byref(c_pstate))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_pstate.value
 
 def nvmlDeviceGetPerformanceState(handle):
     c_pstate = _nvmlPstates_t()
-    fn = get_func_pointer("nvmlDeviceGetPerformanceState")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPerformanceState")
     ret = fn(handle, byref(c_pstate))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_pstate.value
 
 def nvmlDeviceGetPowerManagementMode(handle):
     c_pcapMode = _nvmlEnableState_t()
-    fn = get_func_pointer("nvmlDeviceGetPowerManagementMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerManagementMode")
     ret = fn(handle, byref(c_pcapMode))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_pcapMode.value
 
 def nvmlDeviceGetPowerManagementLimit(handle):
     c_limit = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetPowerManagementLimit")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerManagementLimit")
     ret = fn(handle, byref(c_limit))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_limit.value
 
 # Added in 4.304
 def nvmlDeviceGetPowerManagementLimitConstraints(handle):
     c_minLimit = c_uint()
     c_maxLimit = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetPowerManagementLimitConstraints")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerManagementLimitConstraints")
     ret = fn(handle, byref(c_minLimit), byref(c_maxLimit))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return [c_minLimit.value, c_maxLimit.value]
 
 # Added in 4.304
 def nvmlDeviceGetPowerManagementDefaultLimit(handle):
     c_limit = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetPowerManagementDefaultLimit")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerManagementDefaultLimit")
     ret = fn(handle, byref(c_limit))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_limit.value
 
 
 # Added in 331
 def nvmlDeviceGetEnforcedPowerLimit(handle):
     c_limit = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetEnforcedPowerLimit")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetEnforcedPowerLimit")
     ret = fn(handle, byref(c_limit))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_limit.value
 
 def nvmlDeviceGetPowerUsage(handle):
-    c_mWatts = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetPowerUsage")
-    ret = fn(handle, byref(c_mWatts))
-    check_return(ret)
-    return c_mWatts.value
+    c_watts = c_uint()
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPowerUsage")
+    ret = fn(handle, byref(c_watts))
+    _nvmlCheckReturn(ret)
+    return c_watts.value
 
 def nvmlDeviceGetTotalEnergyConsumption(handle):
-    c_mJoules = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetTotalEnergyConsumption")
-    ret = fn(handle, byref(c_mJoules))
-    check_return(ret)
-    return c_mJoules.value
+    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 = get_func_pointer("nvmlDeviceGetGpuOperationMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuOperationMode")
     ret = fn(handle, byref(c_currState), byref(c_pendingState))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return [c_currState.value, c_pendingState.value]
 
 # Added in 4.304
@@ -1270,44 +2152,40 @@ def nvmlDeviceGetPendingGpuOperationMode(handle):
     return nvmlDeviceGetGpuOperationMode(handle)[1]
 
 def nvmlDeviceGetMemoryInfo(handle):
-    """Retrieves memory object.
-
-    Return object includes the amount of used, free and total memory available
-    on the device, in bytes.
-
-    Args:
-        handle: The identifier of the target device
-
-    Returns:
-        memory: The return value. An `nvmlMemory_t` object
-
-    """
     c_memory = c_nvmlMemory_t()
-    fn = get_func_pointer("nvmlDeviceGetMemoryInfo")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetMemoryInfo")
     ret = fn(handle, byref(c_memory))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_memory
 
 def nvmlDeviceGetBAR1MemoryInfo(handle):
     c_bar1_memory = c_nvmlBAR1Memory_t()
-    fn = get_func_pointer("nvmlDeviceGetBAR1MemoryInfo")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetBAR1MemoryInfo")
     ret = fn(handle, byref(c_bar1_memory))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_bar1_memory
 
 def nvmlDeviceGetComputeMode(handle):
     c_mode = _nvmlComputeMode_t()
-    fn = get_func_pointer("nvmlDeviceGetComputeMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetComputeMode")
     ret = fn(handle, byref(c_mode))
-    check_return(ret)
+    _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 = get_func_pointer("nvmlDeviceGetEccMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetEccMode")
     ret = fn(handle, byref(c_currState), byref(c_pendingState))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return [c_currState.value, c_pendingState.value]
 
 # added to API
@@ -1320,69 +2198,69 @@ def nvmlDeviceGetPendingEccMode(handle):
 
 def nvmlDeviceGetTotalEccErrors(handle, errorType, counterType):
     c_count = c_ulonglong()
-    fn = get_func_pointer("nvmlDeviceGetTotalEccErrors")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetTotalEccErrors")
     ret = fn(handle, _nvmlMemoryErrorType_t(errorType),
-	         _nvmlEccCounterType_t(counterType), byref(c_count))
-    check_return(ret)
+                 _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 = get_func_pointer("nvmlDeviceGetDetailedEccErrors")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetDetailedEccErrors")
     ret = fn(handle, _nvmlMemoryErrorType_t(errorType),
-	         _nvmlEccCounterType_t(counterType), byref(c_counts))
-    check_return(ret)
+                 _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 = get_func_pointer("nvmlDeviceGetMemoryErrorCounter")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetMemoryErrorCounter")
     ret = fn(handle,
              _nvmlMemoryErrorType_t(errorType),
              _nvmlEccCounterType_t(counterType),
              _nvmlMemoryLocation_t(locationType),
              byref(c_count))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_count.value
 
 def nvmlDeviceGetUtilizationRates(handle):
     c_util = c_nvmlUtilization_t()
-    fn = get_func_pointer("nvmlDeviceGetUtilizationRates")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetUtilizationRates")
     ret = fn(handle, byref(c_util))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_util
 
 def nvmlDeviceGetEncoderUtilization(handle):
     c_util = c_uint()
     c_samplingPeriod = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetEncoderUtilization")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetEncoderUtilization")
     ret = fn(handle, byref(c_util), byref(c_samplingPeriod))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return [c_util.value, c_samplingPeriod.value]
 
 def nvmlDeviceGetDecoderUtilization(handle):
     c_util = c_uint()
     c_samplingPeriod = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetDecoderUtilization")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetDecoderUtilization")
     ret = fn(handle, byref(c_util), byref(c_samplingPeriod))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return [c_util.value, c_samplingPeriod.value]
 
 def nvmlDeviceGetPcieReplayCounter(handle):
     c_replay = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetPcieReplayCounter")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPcieReplayCounter")
     ret = fn(handle, byref(c_replay))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_replay.value
 
 def nvmlDeviceGetDriverModel(handle):
     c_currModel = _nvmlDriverModel_t()
     c_pendingModel = _nvmlDriverModel_t()
-    fn = get_func_pointer("nvmlDeviceGetDriverModel")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetDriverModel")
     ret = fn(handle, byref(c_currModel), byref(c_pendingModel))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return [c_currModel.value, c_pendingModel.value]
 
 # added to API
@@ -1396,16 +2274,53 @@ def nvmlDeviceGetPendingDriverModel(handle):
 # Added in 2.285
 def nvmlDeviceGetVbiosVersion(handle):
     c_version = create_string_buffer(NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE)
-    fn = get_func_pointer("nvmlDeviceGetVbiosVersion")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetVbiosVersion")
     ret = fn(handle, c_version, c_uint(NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_version.value
 
 # Added in 2.285
+def nvmlDeviceGetComputeRunningProcesses_v2(handle):
+    # first call to get the size
+    c_count = c_uint(0)
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetComputeRunningProcesses_v2")
+    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_v2(handle);
+
+def nvmlDeviceGetGraphicsRunningProcesses_v2(handle):
     # first call to get the size
     c_count = c_uint(0)
-    fn = get_func_pointer("nvmlDeviceGetComputeRunningProcesses")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetGraphicsRunningProcesses_v2")
     ret = fn(handle, byref(c_count), None)
 
     if (ret == NVML_SUCCESS):
@@ -1420,12 +2335,12 @@ def nvmlDeviceGetComputeRunningProcesses(handle):
 
         # make the call again
         ret = fn(handle, byref(c_count), c_procs)
-        check_return(ret)
+        _nvmlCheckReturn(ret)
 
         procs = []
         for i in range(c_count.value):
             # use an alternative struct for this object
-            obj = struct_to_friendly_object(c_procs[i])
+            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
@@ -1437,9 +2352,15 @@ def nvmlDeviceGetComputeRunningProcesses(handle):
         raise NVMLError(ret)
 
 def nvmlDeviceGetGraphicsRunningProcesses(handle):
+    return nvmlDeviceGetGraphicsRunningProcesses_v2(handle)
+
+def nvmlDeviceGetMPSComputeRunningProcesses(handle):
+    return nvmlDeviceGetMPSComputeRunningProcesses_v2(handle)
+
+def nvmlDeviceGetMPSComputeRunningProcesses_v2(handle):
     # first call to get the size
     c_count = c_uint(0)
-    fn = get_func_pointer("nvmlDeviceGetGraphicsRunningProcesses")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetMPSComputeRunningProcesses_v2")
     ret = fn(handle, byref(c_count), None)
 
     if (ret == NVML_SUCCESS):
@@ -1454,12 +2375,12 @@ def nvmlDeviceGetGraphicsRunningProcesses(handle):
 
         # make the call again
         ret = fn(handle, byref(c_count), c_procs)
-        check_return(ret)
+        _nvmlCheckReturn(ret)
 
         procs = []
         for i in range(c_count.value):
             # use an alternative struct for this object
-            obj = struct_to_friendly_object(c_procs[i])
+            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
@@ -1473,219 +2394,250 @@ def nvmlDeviceGetGraphicsRunningProcesses(handle):
 def nvmlDeviceGetAutoBoostedClocksEnabled(handle):
     c_isEnabled = _nvmlEnableState_t()
     c_defaultIsEnabled = _nvmlEnableState_t()
-    fn = get_func_pointer("nvmlDeviceGetAutoBoostedClocksEnabled")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetAutoBoostedClocksEnabled")
     ret = fn(handle, byref(c_isEnabled), byref(c_defaultIsEnabled))
-    check_return(ret)
+    _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 = get_func_pointer("nvmlUnitSetLedState")
+    fn = _nvmlGetFunctionPointer("nvmlUnitSetLedState")
     ret = fn(unit, _nvmlLedColor_t(color))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceSetPersistenceMode(handle, mode):
-    fn = get_func_pointer("nvmlDeviceSetPersistenceMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetPersistenceMode")
     ret = fn(handle, _nvmlEnableState_t(mode))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceSetComputeMode(handle, mode):
-    fn = get_func_pointer("nvmlDeviceSetComputeMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetComputeMode")
     ret = fn(handle, _nvmlComputeMode_t(mode))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceSetEccMode(handle, mode):
-    fn = get_func_pointer("nvmlDeviceSetEccMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetEccMode")
     ret = fn(handle, _nvmlEnableState_t(mode))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceClearEccErrorCounts(handle, counterType):
-    fn = get_func_pointer("nvmlDeviceClearEccErrorCounts")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceClearEccErrorCounts")
     ret = fn(handle, _nvmlEccCounterType_t(counterType))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceSetDriverModel(handle, model):
-    fn = get_func_pointer("nvmlDeviceSetDriverModel")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetDriverModel")
     ret = fn(handle, _nvmlDriverModel_t(model))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceSetAutoBoostedClocksEnabled(handle, enabled):
-    fn = get_func_pointer("nvmlDeviceSetAutoBoostedClocksEnabled")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetAutoBoostedClocksEnabled")
     ret = fn(handle, _nvmlEnableState_t(enabled))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
     #Throws NVML_ERROR_NOT_SUPPORTED if hardware doesn't support setting auto boosted clocks
 
 def nvmlDeviceSetDefaultAutoBoostedClocksEnabled(handle, enabled, flags):
-    fn = get_func_pointer("nvmlDeviceSetDefaultAutoBoostedClocksEnabled")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetDefaultAutoBoostedClocksEnabled")
     ret = fn(handle, _nvmlEnableState_t(enabled), c_uint(flags))
-    check_return(ret)
+    _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 = get_func_pointer("nvmlDeviceSetApplicationsClocks")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetApplicationsClocks")
     ret = fn(handle, c_uint(maxMemClockMHz), c_uint(maxGraphicsClockMHz))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 # Added in 4.304
 def nvmlDeviceResetApplicationsClocks(handle):
-    fn = get_func_pointer("nvmlDeviceResetApplicationsClocks")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceResetApplicationsClocks")
     ret = fn(handle)
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 # Added in 4.304
 def nvmlDeviceSetPowerManagementLimit(handle, limit):
-    fn = get_func_pointer("nvmlDeviceSetPowerManagementLimit")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetPowerManagementLimit")
     ret = fn(handle, c_uint(limit))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 # Added in 4.304
 def nvmlDeviceSetGpuOperationMode(handle, mode):
-    fn = get_func_pointer("nvmlDeviceSetGpuOperationMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetGpuOperationMode")
     ret = fn(handle, _nvmlGpuOperationMode_t(mode))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 # Added in 2.285
 def nvmlEventSetCreate():
-    fn = get_func_pointer("nvmlEventSetCreate")
+    fn = _nvmlGetFunctionPointer("nvmlEventSetCreate")
     eventSet = c_nvmlEventSet_t()
     ret = fn(byref(eventSet))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return eventSet
 
 # Added in 2.285
 def nvmlDeviceRegisterEvents(handle, eventTypes, eventSet):
-    fn = get_func_pointer("nvmlDeviceRegisterEvents")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceRegisterEvents")
     ret = fn(handle, c_ulonglong(eventTypes), eventSet)
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 # Added in 2.285
 def nvmlDeviceGetSupportedEventTypes(handle):
     c_eventTypes = c_ulonglong()
-    fn = get_func_pointer("nvmlDeviceGetSupportedEventTypes")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetSupportedEventTypes")
     ret = fn(handle, byref(c_eventTypes))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_eventTypes.value
 
-# Added in 2.285
 # raises NVML_ERROR_TIMEOUT exception on timeout
-def nvmlEventSetWait(eventSet, timeoutms):
-    fn = get_func_pointer("nvmlEventSetWait")
+def nvmlEventSetWait_v2(eventSet, timeoutms):
+    fn = _nvmlGetFunctionPointer("nvmlEventSetWait_v2")
     data = c_nvmlEventData_t()
     ret = fn(eventSet, byref(data), c_uint(timeoutms))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return data
 
+def nvmlEventSetWait(eventSet, timeoutms):
+    return nvmlEventSetWait_v2(eventSet, timeoutms)
+
 # Added in 2.285
 def nvmlEventSetFree(eventSet):
-    fn = get_func_pointer("nvmlEventSetFree")
+    fn = _nvmlGetFunctionPointer("nvmlEventSetFree")
     ret = fn(eventSet)
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 # Added in 3.295
 def nvmlDeviceOnSameBoard(handle1, handle2):
-    fn = get_func_pointer("nvmlDeviceOnSameBoard")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceOnSameBoard")
     onSameBoard = c_int()
     ret = fn(handle1, handle2, byref(onSameBoard))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return (onSameBoard.value != 0)
 
 # Added in 3.295
 def nvmlDeviceGetCurrPcieLinkGeneration(handle):
-    fn = get_func_pointer("nvmlDeviceGetCurrPcieLinkGeneration")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetCurrPcieLinkGeneration")
     gen = c_uint()
     ret = fn(handle, byref(gen))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return gen.value
 
 # Added in 3.295
 def nvmlDeviceGetMaxPcieLinkGeneration(handle):
-    fn = get_func_pointer("nvmlDeviceGetMaxPcieLinkGeneration")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetMaxPcieLinkGeneration")
     gen = c_uint()
     ret = fn(handle, byref(gen))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return gen.value
 
 # Added in 3.295
 def nvmlDeviceGetCurrPcieLinkWidth(handle):
-    fn = get_func_pointer("nvmlDeviceGetCurrPcieLinkWidth")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetCurrPcieLinkWidth")
     width = c_uint()
     ret = fn(handle, byref(width))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return width.value
 
 # Added in 3.295
 def nvmlDeviceGetMaxPcieLinkWidth(handle):
-    fn = get_func_pointer("nvmlDeviceGetMaxPcieLinkWidth")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetMaxPcieLinkWidth")
     width = c_uint()
     ret = fn(handle, byref(width))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return width.value
 
 # Added in 4.304
 def nvmlDeviceGetSupportedClocksThrottleReasons(handle):
     c_reasons= c_ulonglong()
-    fn = get_func_pointer("nvmlDeviceGetSupportedClocksThrottleReasons")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetSupportedClocksThrottleReasons")
     ret = fn(handle, byref(c_reasons))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_reasons.value
 
 # Added in 4.304
 def nvmlDeviceGetCurrentClocksThrottleReasons(handle):
     c_reasons= c_ulonglong()
-    fn = get_func_pointer("nvmlDeviceGetCurrentClocksThrottleReasons")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetCurrentClocksThrottleReasons")
     ret = fn(handle, byref(c_reasons))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_reasons.value
 
 # Added in 5.319
 def nvmlDeviceGetIndex(handle):
-    fn = get_func_pointer("nvmlDeviceGetIndex")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetIndex")
     c_index = c_uint()
     ret = fn(handle, byref(c_index))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_index.value
 
 # Added in 5.319
 def nvmlDeviceGetAccountingMode(handle):
     c_mode = _nvmlEnableState_t()
-    fn = get_func_pointer("nvmlDeviceGetAccountingMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetAccountingMode")
     ret = fn(handle, byref(c_mode))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_mode.value
 
 def nvmlDeviceSetAccountingMode(handle, mode):
-    fn = get_func_pointer("nvmlDeviceSetAccountingMode")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetAccountingMode")
     ret = fn(handle, _nvmlEnableState_t(mode))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceClearAccountingPids(handle):
-    fn = get_func_pointer("nvmlDeviceClearAccountingPids")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceClearAccountingPids")
     ret = fn(handle)
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceGetAccountingStats(handle, pid):
     stats = c_nvmlAccountingStats_t()
-    fn = get_func_pointer("nvmlDeviceGetAccountingStats")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetAccountingStats")
     ret = fn(handle, c_uint(pid), byref(stats))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     if (stats.maxMemoryUsage == NVML_VALUE_NOT_AVAILABLE_ulonglong.value):
         # special case for WDDM on Windows, see comment above
         stats.maxMemoryUsage = None
@@ -1694,22 +2646,22 @@ def nvmlDeviceGetAccountingStats(handle, pid):
 def nvmlDeviceGetAccountingPids(handle):
     count = c_uint(nvmlDeviceGetAccountingBufferSize(handle))
     pids = (c_uint * count.value)()
-    fn = get_func_pointer("nvmlDeviceGetAccountingPids")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetAccountingPids")
     ret = fn(handle, byref(count), pids)
-    check_return(ret)
-    return map(int, pids[0:count.value])
+    _nvmlCheckReturn(ret)
+    return list(map(int, pids[0:count.value]))
 
 def nvmlDeviceGetAccountingBufferSize(handle):
     bufferSize = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetAccountingBufferSize")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetAccountingBufferSize")
     ret = fn(handle, byref(bufferSize))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return int(bufferSize.value)
 
 def nvmlDeviceGetRetiredPages(device, sourceFilter):
     c_source = _nvmlPageRetirementCause_t(sourceFilter)
     c_count = c_uint(0)
-    fn = get_func_pointer("nvmlDeviceGetRetiredPages")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetRetiredPages")
 
     # First call will get the size
     ret = fn(device, c_source, byref(c_count), None)
@@ -1726,34 +2678,59 @@ def nvmlDeviceGetRetiredPages(device, sourceFilter):
     page_array = c_ulonglong * c_count.value
     c_pages = page_array()
     ret = fn(device, c_source, byref(c_count), c_pages)
-    check_return(ret)
-    return map(int, c_pages[0:c_count.value])
+    _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 = get_func_pointer("nvmlDeviceGetRetiredPagesPendingStatus")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetRetiredPagesPendingStatus")
     ret = fn(device, byref(c_pending))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return int(c_pending.value)
 
 def nvmlDeviceGetAPIRestriction(device, apiType):
     c_permission = _nvmlEnableState_t()
-    fn = get_func_pointer("nvmlDeviceGetAPIRestriction")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetAPIRestriction")
     ret = fn(device, _nvmlRestrictedAPI_t(apiType), byref(c_permission))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return int(c_permission.value)
 
 def nvmlDeviceSetAPIRestriction(handle, apiType, isRestricted):
-    fn = get_func_pointer("nvmlDeviceSetAPIRestriction")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetAPIRestriction")
     ret = fn(handle, _nvmlRestrictedAPI_t(apiType), _nvmlEnableState_t(isRestricted))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return None
 
 def nvmlDeviceGetBridgeChipInfo(handle):
     bridgeHierarchy = c_nvmlBridgeChipHierarchy_t()
-    fn = get_func_pointer("nvmlDeviceGetBridgeChipInfo")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetBridgeChipInfo")
     ret = fn(handle, byref(bridgeHierarchy))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return bridgeHierarchy
 
 def nvmlDeviceGetSamples(device, sampling_type, timeStamp):
@@ -1761,7 +2738,7 @@ def nvmlDeviceGetSamples(device, sampling_type, timeStamp):
     c_time_stamp = c_ulonglong(timeStamp)
     c_sample_count = c_uint(0)
     c_sample_value_type = _nvmlValueType_t()
-    fn = get_func_pointer("nvmlDeviceGetSamples")
+    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)
@@ -1773,46 +2750,45 @@ def nvmlDeviceGetSamples(device, sampling_type, timeStamp):
     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)
-    check_return(ret)
+    _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 = get_func_pointer("nvmlDeviceGetViolationStatus")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetViolationStatus")
 
     ## Invoke the method to get violation time
     ret = fn(device, c_perfPolicy_type, byref(c_violTime))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_violTime
 
 def nvmlDeviceGetPcieThroughput(device, counter):
     c_util = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetPcieThroughput")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetPcieThroughput")
     ret = fn(device, _nvmlPcieUtilCounter_t(counter), byref(c_util))
-    check_return(ret)
+    _nvmlCheckReturn(ret)
     return c_util.value
 
 def nvmlSystemGetTopologyGpuSet(cpuNumber):
     c_count = c_uint(0)
-    fn = get_func_pointer("nvmlSystemGetTopologyGpuSet")
+    fn = _nvmlGetFunctionPointer("nvmlSystemGetTopologyGpuSet")
 
     # First call will get the size
     ret = fn(cpuNumber, byref(c_count), None)
 
     if ret != NVML_SUCCESS:
         raise NVMLError(ret)
-    print(c_count.value)
     # 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)
-    check_return(ret)
-    return map(None, c_devices[0:c_count.value])
+    _nvmlCheckReturn(ret)
+    return list(c_devices[0:c_count.value])
 
 def nvmlDeviceGetTopologyNearestGpus(device, level):
     c_count = c_uint(0)
-    fn = get_func_pointer("nvmlDeviceGetTopologyNearestGpus")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetTopologyNearestGpus")
 
     # First call will get the size
     ret = fn(device, level, byref(c_count), None)
@@ -1824,272 +2800,946 @@ def nvmlDeviceGetTopologyNearestGpus(device, level):
     device_array = c_nvmlDevice_t * c_count.value
     c_devices = device_array()
     ret = fn(device, level, byref(c_count), c_devices)
-    check_return(ret)
-    return map(None, c_devices[0:c_count.value])
+    _nvmlCheckReturn(ret)
+    return list(c_devices[0:c_count.value])
 
 def nvmlDeviceGetTopologyCommonAncestor(device1, device2):
     c_level = _nvmlGpuTopologyLevel_t()
-    fn = get_func_pointer("nvmlDeviceGetTopologyCommonAncestor")
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetTopologyCommonAncestor")
     ret = fn(device1, device2, byref(c_level))
-    check_return(ret)
+    _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):
-    """Freeze the NVLINK utilization counters.
+    fn = _nvmlGetFunctionPointer("nvmlDeviceFreezeNvLinkUtilizationCounter")
+    ret = fn(device, link, counter, freeze)
+    _nvmlCheckReturn(ret)
+    return None
 
-    Freeze the NVLINK utilization counters. Both the receive and transmit
-    counters are operated on by this function.
+def nvmlDeviceResetNvLinkUtilizationCounter(device, link, counter):
+    fn = _nvmlGetFunctionPointer("nvmlDeviceResetNvLinkUtilizationCounter")
+    ret = fn(device, link, counter)
+    _nvmlCheckReturn(ret)
+    return None
 
-    Args:
-        device: The identifier of the target device
+def nvmlDeviceSetNvLinkUtilizationControl(device, link, counter, control, reset):
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetNvLinkUtilizationControl")
+    ret = fn(device, link, counter, byref(control), reset)
+    _nvmlCheckReturn(ret)
+    return None
 
-        link: Specifies the NvLink link to be queried (uint)
+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
 
-        freeze: NVML_FEATURE_ENABLED(1) = freeze the rx and tx counters
-                NVML_FEATURE_DISABLED(0) = unfreeze the rx and tx counters
+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
 
-    """
-    c_link = c_uint(link)
-    c_counter = c_uint(counter)
-    fn = get_func_pointer("nvmlDeviceFreezeNvLinkUtilizationCounter")
-    ret = fn(device, c_link, c_counter, _nvmlEnableState_t(freeze))
-    return check_return(ret)
+def nvmlDeviceResetNvLinkErrorCounters(device, link):
+    fn = _nvmlGetFunctionPointer("nvmlDeviceResetNvLinkErrorCounters")
+    ret = fn(device, link)
+    _nvmlCheckReturn(ret)
+    return None
 
-def nvmlDeviceGetNvLinkCapability(device, link, cap):
-    """Retrieve the capability of a specified NvLinklink.
+def nvmlDeviceGetNvLinkRemotePciInfo(device, link):
+    c_pci = nvmlPciInfo_t()
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkRemotePciInfo_v2")
+    ret = fn(device, link, byref(c_pci))
+    _nvmlCheckReturn(ret)
+    return c_pci
 
-    Retrieves the requested capability from the device's NvLink for the link
-    specified. Please refer to the nvmlNvLinkCapability_t structure for the
-    specific caps that can be queried. The return value should be treated as a
-    boolean.
+def nvmlDeviceGetNvLinkRemoteDeviceType(handle, link):
+    c_type = _nvmlNvLinkDeviceType_t()
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkRemoteDeviceType")
+    ret = fn(handle, link, byref(c_type))
+    _nvmlCheckReturn(ret)
+    return c_type.value
 
-    Args:
-        device: The identifier of the target device
+def nvmlDeviceGetNvLinkState(device, link):
+    c_isActive = c_uint()
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkState")
+    ret = fn(device, link, byref(c_isActive))
+    _nvmlCheckReturn(ret)
+    return c_isActive.value
 
-        link: Specifies the NvLink link to be queried (uint)
+def nvmlDeviceGetNvLinkVersion(device, link):
+    c_version = c_uint()
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetNvLinkVersion")
+    ret = fn(device, link, byref(c_version))
+    _nvmlCheckReturn(ret)
+    return c_version.value
 
-        capability: Specifies the nvmlNvLinkCapability_t to be queried
+def nvmlDeviceModifyDrainState(pciInfo, newState):
+    fn = _nvmlGetFunctionPointer("nvmlDeviceModifyDrainState")
+    ret = fn(pointer(pciInfo), newState)
+    _nvmlCheckReturn(ret)
+    return None
 
-    Returns:
-        cap_result: A boolean for the queried capability indicating that feature
-        is available
+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
 
-    """
-    c_link = c_uint(link)
-    c_cap_result = c_bool()
-    fn = get_func_pointer("nvmlDeviceGetNvLinkCapability")
-    ret = fn(device, c_link, _nvmlNvLinkCapability_t(cap), byref(c_cap_result))
-    check_return(ret)
-    return c_cap_result.value
+def nvmlDeviceDiscoverGpus(pciInfo):
+    fn = _nvmlGetFunctionPointer("nvmlDeviceDiscoverGpus")
+    ret = fn(pointer(pciInfo))
+    _nvmlCheckReturn(ret)
+    return None
 
-def nvmlDeviceGetNvLinkErrorCounter(device, link, counter):
-    """Retrieve the specified error counter value.
+def nvmlDeviceGetFieldValues(handle, fieldIds):
+    values_arr = c_nvmlFieldValue_t * len(fieldIds)
+    values = values_arr()
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetFieldValues")
 
-    Retrieves the specified error counter value. Please refer to
-    _nvmlNvLinkErrorCounter_t for error counters that are available.
+    for i, fieldId in enumerate(fieldIds):
+        try:
+            (values[i].fieldId, values[i].scopeId) = fieldId
+        except TypeError:
+            values[i].fieldId = fieldId
 
-    Args:
-        device: The identifier of the target device
+    ret = fn(handle, c_int32(len(fieldIds)), byref(values))
+    _nvmlCheckReturn(ret)
+    return values
 
-        link: Specifies the NvLink link to be queried (uint)
+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
 
-        counter: Specifies the NvLink counter to be queried
+def nvmlDeviceSetVirtualizationMode(handle, virtualization_mode):
+    fn = _nvmlGetFunctionPointer("nvmlDeviceSetVirtualizationMode")
+    return fn(handle, virtualization_mode)
 
-    Returns:
-        value: The specified counter value
 
-    """
-    c_link = c_uint(link)
-    c_cap_result = c_bool()
-    c_value = c_ulonglong()
-    fn = get_func_pointer("nvmlDeviceGetNvLinkErrorCounter")
-    ret = fn(device, c_link, _nvmlNvLinkErrorCounter_t(counter), byref(c_value))
-    check_return(ret)
-    return c_value.value
+def nvmlDeviceGetSupportedVgpus(handle):
+    # first call to get the size
+    c_vgpu_count = c_uint(0)
 
-def nvmlDeviceGetNvLinkRemotePciInfo(device, link):
-    """Retrieve the PCI information for the remote node on a NvLink link.
+    fn =  _nvmlGetFunctionPointer("nvmlDeviceGetSupportedVgpus")
+    ret = fn(handle, byref(c_vgpu_count), None)
 
-    Retrieves the PCI information for the remote node on a NvLink link. Note:
-    pciSubSystemId is not filled in this function and is indeterminate.
+    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()
 
-    Args:
-        device: The identifier of the target device
+        # 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)
 
-        link: Specifies the NvLink link to be queried (uint)
+def nvmlDeviceGetCreatableVgpus(handle):
+    # first call to get the size
+    c_vgpu_count = c_uint(0)
 
-    Returns:
-        pci: nvmlPciInfo_t of the remote node for the specified link
+    fn =  _nvmlGetFunctionPointer("nvmlDeviceGetCreatableVgpus")
+    ret = fn(handle, byref(c_vgpu_count), None)
 
-    """
-    c_link = c_uint(link)
-    c_pci = c_nvmlPciInfo_t()
-    fn = get_func_pointer("nvmlDeviceGetNvLinkRemotePciInfo")
-    ret = fn(device, c_link, byref(c_pci))
-    check_return(ret)
-    return c_pci
+    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()
 
-def nvmlDeviceGetNvLinkState(device, link):
-    """Retrieve the state of the device's NvLink for the link specified.
+        # 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)
 
-    Retrieves the state of the device's NvLink for the link specified.
+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)
+
+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
+
+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
 
-    Args:
-        device: The identifier of the target device
+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)
+
+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)
 
-        link: Specifies the NvLink link to be queried (uint)
+    fn  = _nvmlGetFunctionPointer("nvmlDeviceGetActiveVgpus")
+    ret = fn(handle, byref(c_vgpu_count), None)
 
-    Returns:
-        mode: nvmlEnableState_t where NVML_FEATURE_ENABLED indicates that the
-        link is active and NVML_FEATURE_DISABLED indicates it is inactive.
+    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()
 
-    """
-    c_link = c_uint(link)
+        # 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)
+
+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)
+
+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
+
+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
+
+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 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 = get_func_pointer("nvmlDeviceGetNvLinkState")
-    ret = fn(device, c_link, byref(c_mode))
-    check_return(ret)
+    fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetEccMode")
+    ret = fn(vgpuInstance, byref(c_mode))
+    _nvmlCheckReturn(ret)
     return c_mode.value
 
-def nvmlDeviceGetNvLinkUtilizationControl(device, link, counter):
-    """Get NVLINK utilization counter control information
+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 nvmlVgpuInstanceGetGpuInstanceId(vgpuInstance):
+    c_id = c_uint(0)
+    fn  = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetGpuInstanceId")
+    ret = fn(vgpuInstance, byref(c_id))
+    _nvmlCheckReturn(ret)
+    return (c_id.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()
 
-    Get the NVLINK utilization counter control information for the specified
-    counter, 0 or 1. Please refer to nvmlNvLinkUtilizationControl_t for the
-    structure definition. [Note: nvmlNvLinkUtilizationControl_t not documented]
+    fn  = _nvmlGetFunctionPointer("nvmlDeviceGetVgpuUtilization")
+    ret = fn(handle, c_time_stamp, byref(c_sample_value_type), byref(c_vgpu_count), None)
 
-    Args:
-        device: The identifier of the target device
+    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()
 
-        link: Specifies the NvLink link to be queried (uint)
+        # make the call again
+        ret = fn(handle, c_time_stamp, byref(c_sample_value_type), byref(c_vgpu_count), c_samples)
+        _nvmlCheckReturn(ret)
 
-        counter: Specifies the counter that should be set (0 or 1)
+        return c_samples[0:c_vgpu_count.value]
+    else:
+        # error case
+        raise NVMLError(ret)
 
-    Returns:
-        control: The nvmlNvLinkUtilizationControl_t object (an integer)
+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
 
-    """
-    c_link = c_uint(link)
-    c_counter = c_uint(counter)
-    c_control = _nvmlNvLinkUtilizationControl_t()
-    fn = get_func_pointer("nvmlDeviceGetNvLinkUtilizationControl")
-    ret = fn(device, c_link, c_counter, byref(c_control))
-    check_return(ret)
-    return c_control.value
+def nvmlDeviceGetGridLicensableFeatures_v3(handle):
+    c_get_grid_licensable_features = c_nvmlGridLicensableFeatures_v3_t()
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetGridLicensableFeatures_v3")
+    ret = fn(handle, byref(c_get_grid_licensable_features))
+    _nvmlCheckReturn(ret)
 
-def nvmlDeviceGetNvLinkUtilizationCounter(device, link, counter):
-    """Retrieve an NVLINK utilization counter.
+    return (c_get_grid_licensable_features)
 
-    Retrieve the NVLINK utilization counter based on the current control for a
-    specified counter. In general it is good practice to use
-    nvmlDeviceSetNvLinkUtilizationControl before reading the utilization
-    counters as they have no default state.
+def nvmlDeviceGetGridLicensableFeatures(handle):
+    return nvmlDeviceGetGridLicensableFeatures_v3(handle)
 
-    Args:
-        device: The identifier of the target device
+def nvmlDeviceGetEncoderCapacity(handle, encoderQueryType):
+    c_encoder_capacity = c_ulonglong(0)
+    c_encoderQuery_type = _nvmlEncoderQueryType_t(encoderQueryType)
 
-        link: Specifies the NvLink link to be queried (uint)
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetEncoderCapacity")
+    ret = fn(handle, c_encoderQuery_type, byref(c_encoder_capacity))
+    _nvmlCheckReturn(ret)
+    return c_encoder_capacity.value
 
-        counter: Specifies the counter that should be set (0 or 1)
+def nvmlDeviceGetVgpuProcessUtilization(handle, timeStamp):
+    # first call to get the size
+    c_vgpu_count = c_uint(0)
+    c_time_stamp = c_ulonglong(timeStamp)
 
-    Returns:
-        rxtx_dict: Dictionary with `rx` key (value is "receive" counter) and
-        `tx` key (value is "transmit" counter)
+    fn  = _nvmlGetFunctionPointer("nvmlDeviceGetVgpuProcessUtilization")
+    ret = fn(handle, c_time_stamp, byref(c_vgpu_count), None)
 
-    """
-    c_link = c_uint(link)
-    c_counter = c_uint(counter)
-    c_rx = c_ulonglong()
-    c_tx = c_ulonglong()
-    fn = get_func_pointer("nvmlDeviceGetNvLinkUtilizationCounter")
-    ret = fn(device, c_link, c_counter, byref(c_rx), byref(c_tx))
-    check_return(ret)
-    rxtx_dict = {'rx': c_rx.value, 'tx': c_tx.value}
-    return rxtx_dict
+    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()
 
-def nvmlDeviceGetNvLinkVersion(device, link):
-    """Retrieve NvLink version.
+        # make the call again
+        ret = fn(handle, c_time_stamp, byref(c_vgpu_count), c_samples)
+        _nvmlCheckReturn(ret)
 
-    Retrieves the version of the device's NvLink for the link specified.
+        return c_samples[0:c_vgpu_count.value]
+    else:
+        # error case
+        raise NVMLError(ret)
 
-    Args:
-        device: The identifier of the target device
+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)
 
-        link: Specifies the NvLink link to be queried (uint)
+def nvmlDeviceGetEncoderSessions(handle):
+    # first call to get the size
+    c_session_count = c_uint(0)
 
-    Returns:
-        version: Requested NvLink version (uint)
+    fn  = _nvmlGetFunctionPointer("nvmlDeviceGetEncoderSessions")
+    ret = fn(handle, byref(c_session_count), None)
 
-    """
-    c_link = c_uint(link)
-    c_version = c_uint()
-    fn = get_func_pointer("nvmlDeviceGetNvLinkVersion")
-    ret = fn(device, c_link, byref(c_version))
-    check_return(ret)
-    return c_version.value
+    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 nvmlDeviceResetNvLinkErrorCounters(device, link):
-    """Reset all error counters to zero.
+def nvmlDeviceGetFBCStats(handle):
+    c_fbcStats = c_nvmlFBCStats_t()
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetFBCStats")
+    ret = fn(handle, byref(c_fbcStats))
+    _nvmlCheckReturn(ret)
+    return c_fbcStats
 
-    Resets all error counters to zero. Please refer to nvmlNvLinkErrorCounter_t
-    for the list of error counters that are reset.
+def nvmlDeviceGetFBCSessions(handle):
+    # first call to get the size
+    c_session_count = c_uint(0)
 
-    Args:
-        device: The identifier of the target device
+    fn  = _nvmlGetFunctionPointer("nvmlDeviceGetFBCSessions")
+    ret = fn(handle, byref(c_session_count), None)
 
-        link: Specifies the NvLink link to be queried (uint)
+    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)
 
-    """
-    c_link = c_uint(link)
-    fn = get_func_pointer("nvmlDeviceResetNvLinkErrorCounters")
-    ret = fn(device, c_link)
-    return check_return(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 nvmlDeviceResetNvLinkUtilizationCounter(device, link, counter):
-    """Reset the NVLINK utilization counters.
+def nvmlVgpuInstanceGetEncoderSessions(vgpuInstance):
+    # first call to get the size
+    c_session_count = c_uint(0)
 
-    Reset the NVLINK utilization counters. Both the receive and transmit
-    counters are operated on by this function.
+    fn  = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetEncoderSessions")
+    ret = fn(vgpuInstance, byref(c_session_count), None)
 
-    Args:
-        device: The identifier of the target device
+    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)
 
-        link: Specifies the NvLink link to be queried (uint)
+def nvmlVgpuInstanceGetFBCStats(vgpuInstance):
+    c_fbcStats = c_nvmlFBCStats_t()
+    fn = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetFBCStats")
+    ret = fn(vgpuInstance, byref(c_fbcStats))
+    _nvmlCheckReturn(ret)
+    return c_fbcStats
 
-        counter: Specifies the counter that should be reset (0 or 1)
+def nvmlVgpuInstanceGetFBCSessions(vgpuInstance):
+    # first call to get the size
+    c_session_count = c_uint(0)
 
-    """
-    c_link = c_uint(link)
-    c_counter = c_uint(counter)
-    fn = get_func_pointer("nvmlDeviceResetNvLinkUtilizationCounter")
-    ret = fn(device, c_link, c_counter)
-    return check_return(ret)
+    fn  = _nvmlGetFunctionPointer("nvmlVgpuInstanceGetFBCSessions")
+    ret = fn(vgpuInstance, byref(c_session_count), None)
 
-def nvmlDeviceSetNvLinkUtilizationControl(device, link, counter, control, reset):
-    """Set the NVLINK utilization counter control.
+    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)
 
-    Set the NVLINK utilization counter control information for the specified
-    counter, 0 or 1. Please refer to nvmlNvLinkUtilizationControl_t for the
-    structure definition. Performs a reset of the counters if the reset
-    parameter is non-zero. Note: nvmlNvLinkUtilizationControl_t is an integer.
+def nvmlDeviceGetProcessUtilization(handle, timeStamp):
+    # first call to get the size
+    c_count = c_uint(0)
+    c_time_stamp = c_ulonglong(timeStamp)
 
-    Args:
-        device: The identifier of the target device
+    fn  = _nvmlGetFunctionPointer("nvmlDeviceGetProcessUtilization")
+    ret = fn(handle, None, byref(c_count), c_time_stamp)
 
-        link: Specifies the NvLink link to be queried (uint)
+    if (ret == NVML_ERROR_INSUFFICIENT_SIZE):
+        # typical case
+        sampleArray = c_count.value * c_nvmlProcessUtilizationSample_t
+        c_samples = sampleArray()
 
-        counter: Specifies the counter that should be set (0 or 1)
+        # make the call again
+        ret = fn(handle, c_samples, byref(c_count), c_time_stamp)
+        _nvmlCheckReturn(ret)
 
-        reset: Resets the counters on set if non-zero (uint)
+        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
+
+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)
 
-        control: The nvmlNvLinkUtilizationControl_t control setting
-                 Note: 0 == cycles, 1 == packets, 2 == bytes
+def nvmlSetVgpuVersion(vgpuVersion):
+    fn = _nvmlGetFunctionPointer("nvmlSetVgpuVersion")
+    ret = fn(byref(vgpuVersion))
+    _nvmlCheckReturn(ret)
+    return ret
 
-    """
-    c_link = c_uint(link)
-    c_counter = c_uint(counter)
-    c_control = _nvmlNvLinkUtilizationControl_t(control)
-    c_reset = c_uint(reset)
-    fn = get_func_pointer("nvmlDeviceSetNvLinkUtilizationControl")
-    ret = fn(device, c_link, c_counter, byref(c_control), c_reset)
-    return check_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):
+    c_info = c_nvmlGpuInstanceProfileInfo_t()
+    fn = _nvmlGetFunctionPointer("nvmlDeviceGetGpuInstanceProfileInfo")
+    ret = fn(device, profile, byref(c_info))
+    _nvmlCheckReturn(ret)
+    return c_info
+
+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):
+    c_info = c_nvmlComputeInstanceProfileInfo_t()
+    fn = _nvmlGetFunctionPointer("nvmlGpuInstanceGetComputeInstanceProfileInfo")
+    ret = fn(device, profile, engProfile, byref(c_info))
+    _nvmlCheckReturn(ret)
+    return c_info
+
+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 nvmlGpuInstanceCreateComputeInstance(gpuInstance, profileId):
+    c_instance = c_nvmlComputeInstance_t()
+    fn = _nvmlGetFunctionPointer("nvmlGpuInstanceCreateComputeInstance")
+    ret = fn(gpuInstance, profileId, 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
+    
\ No newline at end of file
diff --git a/pynvml/smi.py b/pynvml/smi.py
index 5eb7207..3356705 100755
--- a/pynvml/smi.py
+++ b/pynvml/smi.py
@@ -1,5 +1,5 @@
 # ============================================================================ #
-# Copyright (c) 2011-2019, NVIDIA Corporation.  All rights reserved.
+# 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:
@@ -36,13 +36,13 @@
 From Code:
 DeviceQuery()
 DeviceQuery("--help")
-DeviceQuery("--help_query_gpu")
+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")
+XmlDeviceQuery("--help-query-gpu")
 """
 
 from pynvml.nvml import *
@@ -121,28 +121,40 @@
 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_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_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_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_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
@@ -188,134 +200,151 @@
 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.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.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.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.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,
+    "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",
@@ -447,6 +476,14 @@ def __xmlGetEccByType(handle, counterType, errorType):
           deviceMemory = nvidia_smi.__handleError(err)
       strResult += '          <device_memory>' + nvidia_smi.__toString(deviceMemory) + '</device_memory>\n'
 
+      try:
+          registerFile = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType,
+                                                         NVML_MEMORY_LOCATION_DRAM)
+      except NVMLError as err:
+          registerFile = nvidia_smi.__handleError(err)
+
+      strResult += '          <dram>' + nvidia_smi.__toString(registerFile) + '</dram>\n'
+
       try:
           registerFile = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType,
                                                          NVML_MEMORY_LOCATION_REGISTER_FILE)
@@ -476,6 +513,22 @@ def __xmlGetEccByType(handle, counterType, errorType):
           textureMemory = nvidia_smi.__handleError(err)
       strResult += '          <texture_memory>' + nvidia_smi.__toString(textureMemory) + '</texture_memory>\n'
 
+      try:
+          registerFile = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType,
+                                                         NVML_MEMORY_LOCATION_CBU)
+      except NVMLError as err:
+          registerFile = nvidia_smi.__handleError(err)
+
+      strResult += '          <cbu>' + nvidia_smi.__toString(registerFile) + '</cbu>\n'
+
+      try:
+          registerFile = nvmlDeviceGetMemoryErrorCounter(handle, errorType, counterType,
+                                                         NVML_MEMORY_LOCATION_SRAM)
+      except NVMLError as err:
+          registerFile = nvidia_smi.__handleError(err)
+
+      strResult += '          <sram>' + nvidia_smi.__toString(registerFile) + '</sram>\n'
+
       try:
           count = nvidia_smi.__toString(nvmlDeviceGetTotalEccErrors(handle, errorType, counterType))
       except NVMLError as err:
@@ -497,6 +550,14 @@ def __GetEccByType(handle, counterType, errorType):
 
       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)
@@ -526,6 +587,22 @@ def __GetEccByType(handle, counterType, errorType):
           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:
@@ -543,11 +620,19 @@ def __xmlGetEccByCounter(handle, counterType, filter):
           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>\n'
           eccByCounter += nvidia_smi.__toString(nvidia_smi.__xmlGetEccByType(handle, counterType, NVML_MEMORY_ERROR_TYPE_CORRECTED))
@@ -559,11 +644,19 @@ def __xmlGetEccByCounter(handle, counterType, filter):
           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 += '        <double_bit>\n'
           eccByCounter += nvidia_smi.__toString(nvidia_smi.__xmlGetEccByType(handle, counterType, NVML_MEMORY_ERROR_TYPE_UNCORRECTED))
@@ -581,11 +674,19 @@ def __GetEccByCounter(handle, counterType, filter):
           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)
 
@@ -595,11 +696,18 @@ def __GetEccByCounter(handle, counterType, filter):
           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)
 
@@ -615,11 +723,18 @@ def __xmlGetEcc(handle, filter):
           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>\n'
           ecc += nvidia_smi.__toString(nvidia_smi.__xmlGetEccByCounter(handle, NVML_VOLATILE_ECC, filter))
@@ -632,12 +747,18 @@ def __xmlGetEcc(handle, filter):
           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>\n'
           ecc += nvidia_smi.__toString(nvidia_smi.__xmlGetEccByCounter(handle, NVML_AGGREGATE_ECC, filter))
@@ -656,11 +777,18 @@ def __GetEcc( handle, filter):
           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
@@ -671,12 +799,18 @@ def __GetEcc( handle, filter):
           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
@@ -809,7 +943,7 @@ def __xmlGetClocksThrottleReasons(handle):
               [nvmlClocksThrottleReasonApplicationsClocksSetting, "clocks_throttle_reason_applications_clocks_setting"],
               [nvmlClocksThrottleReasonSwPowerCap,        "clocks_throttle_reason_sw_power_cap"],
               [nvmlClocksThrottleReasonHwSlowdown,        "clocks_throttle_reason_hw_slowdown"],
-              [nvmlClocksThrottleReasonUnknown,           "clocks_throttle_reason_unknown"]
+              [nvmlClocksThrottleReasonNone,           "clocks_throttle_reason_none"]
               ];
 
       strResult = ''
@@ -839,7 +973,7 @@ def __GetClocksThrottleReasons(handle):
               [nvmlClocksThrottleReasonApplicationsClocksSetting, "clocks_throttle_reason_applications_clocks_setting"],
               [nvmlClocksThrottleReasonSwPowerCap,        "clocks_throttle_reason_sw_power_cap"],
               [nvmlClocksThrottleReasonHwSlowdown,        "clocks_throttle_reason_hw_slowdown"],
-              [nvmlClocksThrottleReasonUnknown,           "clocks_throttle_reason_unknown"]
+              [nvmlClocksThrottleReasonNone,           "clocks_throttle_reason_none"]
               ];
 
       clockThrottleReasons = {}
@@ -858,7 +992,7 @@ def __GetClocksThrottleReasons(handle):
           clockThrottleReasons['Error'] = nvidia_smi.__handleError(err);
 
       return clockThrottleReasons if len(clockThrottleReasons.values()) > 0 else None
-
+    
   #
   # Converts errors into string messages
   #
@@ -894,7 +1028,7 @@ def XmlDeviceQuery(self, filter=None):
       ---------------------------------------------------------------------------
       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
+      See help_query_gpu.txt or XmlDeviceQuery("--help-query-gpu") for available filter elements
 
       $ XmlDeviceQuery("pci.bus_id,memory.total,memory.free")
 
@@ -996,6 +1130,27 @@ def XmlDeviceQuery(self, filter=None):
 
                   gpuInfo += '    <accounting_mode_buffer_size>' + bufferSize + '</accounting_mode_buffer_size>\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_mm>' + current + '</current_mm>\n'
+                  migMode += '      <pending_mm>' + pending + '</pending_mm>\n'
+                  includeMigMode = True
+
+              if includeMigMode:
+                  gpuInfo += '    <mig_mode>\n'
+                  gpuInfo += migMode
+                  gpuInfo += '    </mig_mode>\n'
+
               driverModel = ''
               includeDriverModel = False
 
@@ -1123,7 +1278,7 @@ def XmlDeviceQuery(self, filter=None):
 
               gpuOperationMode = ''
               includeGOM = False
-              if (NVSMI_ALL in filter or NVSMI_INFOROM_PWR in filter):
+              if (NVSMI_ALL in filter or NVSMI_GOM_CUR in filter):
                   try:
                       current = nvidia_smi.__toStrGOM(nvmlDeviceGetCurrentGpuOperationMode(handle))
                   except NVMLError as err:
@@ -1131,7 +1286,7 @@ def XmlDeviceQuery(self, filter=None):
                   gpuOperationMode += '      <current_gom>' + nvidia_smi.__toString(current) + '</current_gom>\n'
                   includeGOM = True
 
-              if (NVSMI_ALL in filter or NVSMI_INFOROM_PWR in filter):
+              if (NVSMI_ALL in filter or NVSMI_GOM_PENDING in filter):
                   try:
                       pending = nvidia_smi.__toStrGOM(nvmlDeviceGetPendingGpuOperationMode(handle))
                   except NVMLError as err:
@@ -1839,7 +1994,7 @@ def DeviceQuery(self, filter=None):
 
       ---------------------------------------------------------------------------
       For a list of filtered dictionary elements by enumeration value.
-      See help_query_gpu.txt or DeviceQuery("--help_query_gpu") for available filter elements
+      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])
 
@@ -1914,6 +2069,24 @@ def DeviceQuery(self, filter=None):
 
                   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'
@@ -2053,7 +2226,7 @@ def DeviceQuery(self, filter=None):
 
               gpuOperationMode = {}
               includeGOM = False
-              if (NVSMI_ALL in filter or NVSMI_INFOROM_PWR in filter):
+              if (NVSMI_ALL in filter or NVSMI_GOM_CUR in filter):
                   try:
                       current = nvidia_smi.__toStrGOM(nvmlDeviceGetCurrentGpuOperationMode(handle))
                   except NVMLError as err:
@@ -2061,7 +2234,7 @@ def DeviceQuery(self, filter=None):
                   gpuOperationMode['current_gom'] = nvidia_smi.__toString(current)
                   includeGOM = True
 
-              if (NVSMI_ALL in filter or NVSMI_INFOROM_PWR in filter):
+              if (NVSMI_ALL in filter or NVSMI_GOM_PENDING in filter):
                   try:
                       pending = nvidia_smi.__toStrGOM(nvmlDeviceGetPendingGpuOperationMode(handle))
                   except NVMLError as err:
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..6529bfb
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,4 @@
+pip>=9.0.1
+pytest>=3.6,<7.0
+pytest-runner
+pytest-cov


Test patch:
diff --git a/pynvml/tests/test_nvml.py b/pynvml/tests/test_nvml.py
index 09dcbdc..c9e35a9 100644
--- a/pynvml/tests/test_nvml.py
+++ b/pynvml/tests/test_nvml.py
@@ -60,6 +60,11 @@ def test_nvmlSystemGetNVMLVersion(nvml):
     print('[NVML Version: '+vsn+']', end =' ')
     assert vsn > LooseVersion("0.0")
 
+def test_nvmlSystemGetCudaDriverVersion():
+    vsn = 0;
+    vsn = nvml.nvmlSystemGetCudaDriverVersion()
+    assert vsn != 0
+
 # Test pynvml.nvmlSystemGetProcessName
 def test_nvmlSystemGetProcessName(nvml):
     procname = None
@@ -78,6 +83,11 @@ def test_nvmlSystemGetDriverVersion(nvml):
 
 ## Device "Get" Functions (Note: Some functions are fixtures, above) ##
 
+def test_nvmlDeviceGetAttributes(handles):
+    for handle in handles:
+        att = pynvml.nvmlDeviceGetAttributes(handle)
+        assert att is not None
+
 # Test pynvml.nvmlDeviceGetHandleBySerial
 def test_nvmlDeviceGetHandleBySerial(ngpus, serials):
     handles = [ pynvml.nvmlDeviceGetHandleBySerial(serials[i])
@@ -96,6 +106,40 @@ def test_nvmlDeviceGetHandleByPciBusId(ngpus, pci_info):
                 for i in range(ngpus) ]
     assert len(handles) == ngpus
 
+@pytest.mark.parametrize("scope", [
+    pynvml.NVML_AFFINITY_SCOPE_NODE,
+    pynvml.NVML_AFFINITY_SCOPE_SOCKET])
+def test_nvmlDeviceGetMemoryAffinity(handles, scope):
+    size = 1024
+    for handle in handles:
+        nodeSet = pynvml.nvmlDeviceGetMemoryAffinity(handle, size, scope)
+        assert nodeSet is not None
+
+@pytest.mark.parametrize("scope", [
+    pynvml.NVML_AFFINITY_SCOPE_NODE,
+    pynvml.NVML_AFFINITY_SCOPE_SOCKET])
+def test_nvmlDeviceGetCpuAffinityWithinScope(handles, scope):
+    size = 1024
+    for handle in handles:
+        cpuSet = pynvml.nvmlDeviceGetCpuAffinityWithinScope(handle, size, scope)
+        assert cpuSet is not None
+
+@pytest.mark.parametrize("index", [
+    pynvml.NVML_P2P_CAPS_INDEX_READ,
+    pynvml.NVML_P2P_CAPS_INDEX_WRITE,
+    pynvml.NVML_P2P_CAPS_INDEX_NVLINK,
+    pynvml.NVML_P2P_CAPS_INDEX_ATOMICS,
+    pynvml.NVML_P2P_CAPS_INDEX_PROP,
+    pynvml.NVML_P2P_CAPS_INDEX_UNKNOWN
+])
+def test_nvmlDeviceGetP2PStatus(handles, index):
+    for h1 in handles:
+        for h2 in handles:
+            if h1 is not h2:
+                status = pynvml.nvmlDeviceGetP2PStatus(h1, h2, index)
+                assert pynvml.NVML_P2P_STATUS_OK <= status <= pynvml.NVML_P2P_STATUS_UNKNOWN
+
+
 # [Skipping] pynvml.nvmlDeviceGetName
 # [Skipping] pynvml.nvmlDeviceGetBoardId
 # [Skipping] pynvml.nvmlDeviceGetMultiGpuBoard