public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH proxmox-{ve, perl}-rs/common 0/4] use native libnvidia-ml library for vGPU info
@ 2026-01-20 13:13 Christoph Heiss
  2026-01-20 13:13 ` [pve-devel] [PATCH proxmox-ve-rs 1/4] vfio: add crate for interacting with vfio host devices Christoph Heiss
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Christoph Heiss @ 2026-01-20 13:13 UTC (permalink / raw)
  To: pve-devel

Adds support for using the NVML (Nvidia management library) [0] directly
to retrieve information about available (or concrete: creatable at VM
start) vGPUs for Nvidia GPUs. 

This will allow in the future to support anything related to Nvidia
cards/devices in a more stable manner over different driver version, as
NVML provides a proper, independent abstraction.

E.g. the sysfs interface exposed by the driver may change (as it did
recently for kernels 6.8+) and might contain less information, as is now
already the case.  Currently, the "description" column in the mdev type
dropdown under Hardware -> hostpci* is empty for Nvidia vGPUs, since the
6.8 kernel IIRC, due to driver changes.

This restores this functionality, with the description being the result
of `proxmox_ve_vfio::VgpuTypeInfo::description()`, for example:

class=NVS,max-instances=24,max-instances-per-vm=1,
framebuffer-size=1024MiB,num-heads=1,max-resolution=1280x1024,
license=GRID-Virtual-Apps,3.0

In the future, these bindings will also be needed to implement support
for Nvidia MIG (Multi-Instance GPU), for which information are not
exposed in sysfs at all. See also the series [1] sent by Dominik
introducing a new hookscript phase, to, among other things, support
manually setting up MIG. 

[0] https://developer.nvidia.com/management-library-nvml
[1] https://lore.proxmox.com/pve-devel/20260114155043.3313473-1-d.csapak@proxmox.com/

Apply order
===========

proxmox-ve-rs -> proxmox-perl-rs -> pve-common, same as this series is
laid out. Each package will require a bump of previous one.

Diffstat
========

proxmox-ve-rs:

Christoph Heiss (2):
  vfio: add crate for interacting with vfio host devices
  vfio: add rust-native interface for accessing NVIDIA vGPU info

 Cargo.toml                                    |    2 +
 proxmox-ve-vfio/Cargo.toml                    |   18 +
 proxmox-ve-vfio/README.md                     |   25 +
 proxmox-ve-vfio/debian/changelog              |    5 +
 proxmox-ve-vfio/debian/control                |   38 +
 proxmox-ve-vfio/debian/copyright              |   18 +
 proxmox-ve-vfio/debian/debcargo.toml          |    3 +
 .../examples/nv_list_creatable_vgpus.rs       |   15 +
 proxmox-ve-vfio/generate-nvml-bindings.sh     |   27 +
 proxmox-ve-vfio/src/lib.rs                    |    6 +
 proxmox-ve-vfio/src/nvidia/mod.rs             |  126 +
 proxmox-ve-vfio/src/nvidia/nvml/bindings.rs   | 2290 +++++++++++++++++
 proxmox-ve-vfio/src/nvidia/nvml/mod.rs        |  237 ++
 13 files changed, 2810 insertions(+)
 create mode 100644 proxmox-ve-vfio/Cargo.toml
 create mode 100644 proxmox-ve-vfio/README.md
 create mode 100644 proxmox-ve-vfio/debian/changelog
 create mode 100644 proxmox-ve-vfio/debian/control
 create mode 100644 proxmox-ve-vfio/debian/copyright
 create mode 100644 proxmox-ve-vfio/debian/debcargo.toml
 create mode 100644 proxmox-ve-vfio/examples/nv_list_creatable_vgpus.rs
 create mode 100755 proxmox-ve-vfio/generate-nvml-bindings.sh
 create mode 100644 proxmox-ve-vfio/src/lib.rs
 create mode 100644 proxmox-ve-vfio/src/nvidia/mod.rs
 create mode 100644 proxmox-ve-vfio/src/nvidia/nvml/bindings.rs
 create mode 100644 proxmox-ve-vfio/src/nvidia/nvml/mod.rs

proxmox-perl-rs:

Christoph Heiss (1):
  pve: add bindings for proxmox-ve-vfio

 pve-rs/Cargo.toml                          |  1 +
 pve-rs/Makefile                            |  3 +-
 pve-rs/debian/control                      |  1 +
 pve-rs/examples/nv-list-creatable-vgpus.pl | 20 ++++++++++++
 pve-rs/src/lib.rs                          |  1 +
 pve-rs/src/vfio/mod.rs                     |  6 ++++
 pve-rs/src/vfio/nvidia.rs                  | 38 ++++++++++++++++++++++
 7 files changed, 69 insertions(+), 1 deletion(-)
 create mode 100755 pve-rs/examples/nv-list-creatable-vgpus.pl
 create mode 100644 pve-rs/src/vfio/mod.rs
 create mode 100644 pve-rs/src/vfio/nvidia.rs

pve-common:

Christoph Heiss (1):
  sysfs: use new PVE::RS::VFIO::Nvidia module to retrieve vGPU info

 src/PVE/SysFSTools.pm | 45 ++++++++++++++++++++++++++++++-------------
 1 file changed, 32 insertions(+), 13 deletions(-)

-- 
2.47.0



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [pve-devel] [PATCH proxmox-ve-rs 1/4] vfio: add crate for interacting with vfio host devices
  2026-01-20 13:13 [pve-devel] [PATCH proxmox-{ve, perl}-rs/common 0/4] use native libnvidia-ml library for vGPU info Christoph Heiss
@ 2026-01-20 13:13 ` Christoph Heiss
  2026-01-20 13:13 ` [pve-devel] [PATCH proxmox-ve-rs 2/4] vfio: add rust-native interface for accessing NVIDIA vGPU info Christoph Heiss
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Christoph Heiss @ 2026-01-20 13:13 UTC (permalink / raw)
  To: pve-devel

Adds (native library) bindings for NVML [0], generated using bindgen.

This will allow in the future to support anything related to Nvidia
cards/devices in a stable manner over different driver version, as NVML
provides a proper, independent abstraction.

E.g. the sysfs interface exposed by the driver may change (as it did
recently for kernels 6.8+) and might contain more or less information.

[0] https://developer.nvidia.com/management-library-nvml

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
 Cargo.toml                                  |    2 +
 proxmox-ve-vfio/Cargo.toml                  |   18 +
 proxmox-ve-vfio/README.md                   |   25 +
 proxmox-ve-vfio/debian/changelog            |    5 +
 proxmox-ve-vfio/debian/control              |   38 +
 proxmox-ve-vfio/debian/copyright            |   18 +
 proxmox-ve-vfio/debian/debcargo.toml        |    3 +
 proxmox-ve-vfio/generate-nvml-bindings.sh   |   27 +
 proxmox-ve-vfio/src/lib.rs                  |    6 +
 proxmox-ve-vfio/src/nvidia/mod.rs           |    3 +
 proxmox-ve-vfio/src/nvidia/nvml/bindings.rs | 2290 +++++++++++++++++++
 proxmox-ve-vfio/src/nvidia/nvml/mod.rs      |   13 +
 12 files changed, 2448 insertions(+)
 create mode 100644 proxmox-ve-vfio/Cargo.toml
 create mode 100644 proxmox-ve-vfio/README.md
 create mode 100644 proxmox-ve-vfio/debian/changelog
 create mode 100644 proxmox-ve-vfio/debian/control
 create mode 100644 proxmox-ve-vfio/debian/copyright
 create mode 100644 proxmox-ve-vfio/debian/debcargo.toml
 create mode 100755 proxmox-ve-vfio/generate-nvml-bindings.sh
 create mode 100644 proxmox-ve-vfio/src/lib.rs
 create mode 100644 proxmox-ve-vfio/src/nvidia/mod.rs
 create mode 100644 proxmox-ve-vfio/src/nvidia/nvml/bindings.rs
 create mode 100644 proxmox-ve-vfio/src/nvidia/nvml/mod.rs

diff --git a/Cargo.toml b/Cargo.toml
index 99bd54a..6d3c523 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,6 +3,7 @@ members = [
     "proxmox-ve-config",
     "proxmox-frr",
     "proxmox-sdn-types",
+    "proxmox-ve-vfio",
 ]
 exclude = [
     "build",
@@ -15,6 +16,7 @@ edition = "2021"
 license = "AGPL-3"
 homepage = "https://proxmox.com"
 exclude = [ "debian" ]
+repository = "https://git.proxmox.com/?p=proxmox-ve-rs.git"
 rust-version = "1.82"
 
 [workspace.dependencies]
diff --git a/proxmox-ve-vfio/Cargo.toml b/proxmox-ve-vfio/Cargo.toml
new file mode 100644
index 0000000..d5d7fc3
--- /dev/null
+++ b/proxmox-ve-vfio/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "proxmox-ve-vfio"
+version = "0.1.0"
+description = "Library for handling VFIO host devices such as (v)GPUs"
+authors = [
+    "Christoph Heiss <c.heiss@proxmox.com>",
+    "Proxmox Support Team <support@proxmox.com>"
+]
+edition.workspace = true
+exclude.workspace = true
+homepage.workspace = true
+license.workspace = true
+
+[dependencies]
+anyhow.workspace = true
+serde = { workspace = true, features = [ "derive" ] }
+
+libloading = "0.8"
diff --git a/proxmox-ve-vfio/README.md b/proxmox-ve-vfio/README.md
new file mode 100644
index 0000000..306f377
--- /dev/null
+++ b/proxmox-ve-vfio/README.md
@@ -0,0 +1,25 @@
+# proxmox-ve-vfio
+
+A rust crate for handling host devices such as (v)GPUs. Currently only minimal
+support for Nvidia vGPU information retrieval is implemented.
+
+## NVML bindings
+
+This create uses the [NVML](https://developer.nvidia.com/management-library-nvml) for communicating
+with Nvidia GPUs. The bindings are pre-generated as `src/bindings.rs` from the `nvml.h` header file,
+which is contained within the CUDA Toolkit.
+
+When the CUDA toolkit is installed, the header can be found at 
+`/usr/local/cuda-<version>/targets/x86_64-linux/include/nvml.h`.
+
+It can also be found online in o https://github.com/NVIDIA/nvidia-settings/blob/main/src/nvml.h
+
+Current bindings are generated from the **13.1 CUDA Toolkit** release.
+
+### Re-generate bindings
+
+[`bindgen`](https://github.com/rust-lang/rust-bindgen) is required.
+
+```sh
+./generate-nvml-bindings.sh <path-to-nvml.h>
+```
diff --git a/proxmox-ve-vfio/debian/changelog b/proxmox-ve-vfio/debian/changelog
new file mode 100644
index 0000000..b483baf
--- /dev/null
+++ b/proxmox-ve-vfio/debian/changelog
@@ -0,0 +1,5 @@
+rust-proxmox-ve-vfio (0.1.0-1) UNRELEASED; urgency=medium
+
+  * Initial package.
+
+ -- Proxmox Support Team <support@proxmox.com>  Mon, 19 Jan 2026 10:45:17 +0100
diff --git a/proxmox-ve-vfio/debian/control b/proxmox-ve-vfio/debian/control
new file mode 100644
index 0000000..529d19e
--- /dev/null
+++ b/proxmox-ve-vfio/debian/control
@@ -0,0 +1,38 @@
+Source: rust-proxmox-ve-vfio
+Section: rust
+Priority: optional
+Build-Depends: debhelper-compat (= 13),
+ dh-sequence-cargo
+Build-Depends-Arch: cargo:native <!nocheck>,
+ rustc:native <!nocheck>,
+ libstd-rust-dev <!nocheck>,
+ librust-anyhow-1+default-dev <!nocheck>,
+ librust-libloading-0.8+default-dev <!nocheck>,
+ librust-serde-1+default-dev <!nocheck>,
+ librust-serde-1+derive-dev <!nocheck>
+Maintainer: Proxmox Support Team <support@proxmox.com>
+Standards-Version: 4.7.2
+Vcs-Git: https://salsa.debian.org/rust-team/debcargo-conf.git [src/proxmox-ve-vfio]
+Vcs-Browser: https://salsa.debian.org/rust-team/debcargo-conf/tree/master/src/proxmox-ve-vfio
+Homepage: https://proxmox.com
+X-Cargo-Crate: proxmox-ve-vfio
+
+Package: librust-proxmox-ve-vfio-dev
+Architecture: any
+Multi-Arch: same
+Depends:
+ ${misc:Depends},
+ librust-anyhow-1+default-dev,
+ librust-libloading-0.8+default-dev,
+ librust-serde-1+default-dev,
+ librust-serde-1+derive-dev
+Provides:
+ librust-proxmox-ve-vfio+default-dev (= ${binary:Version}),
+ librust-proxmox-ve-vfio-0-dev (= ${binary:Version}),
+ librust-proxmox-ve-vfio-0+default-dev (= ${binary:Version}),
+ librust-proxmox-ve-vfio-0.1-dev (= ${binary:Version}),
+ librust-proxmox-ve-vfio-0.1+default-dev (= ${binary:Version}),
+ librust-proxmox-ve-vfio-0.1.0-dev (= ${binary:Version}),
+ librust-proxmox-ve-vfio-0.1.0+default-dev (= ${binary:Version})
+Description: Handling VFIO host devices such as (v)GPUs - Rust source code
+ Source code for Debianized Rust crate "proxmox-ve-vfio"
diff --git a/proxmox-ve-vfio/debian/copyright b/proxmox-ve-vfio/debian/copyright
new file mode 100644
index 0000000..01138fa
--- /dev/null
+++ b/proxmox-ve-vfio/debian/copyright
@@ -0,0 +1,18 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+
+Files:
+ *
+Copyright: 2026 Proxmox Server Solutions GmbH <support@proxmox.com>
+License: AGPL-3.0-or-later
+ This program is free software: you can redistribute it and/or modify it under
+ the terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your option) any
+ later version.
+ .
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+ details.
+ .
+ You should have received a copy of the GNU Affero General Public License along
+ with this program. If not, see <https://www.gnu.org/licenses/>.
diff --git a/proxmox-ve-vfio/debian/debcargo.toml b/proxmox-ve-vfio/debian/debcargo.toml
new file mode 100644
index 0000000..db431df
--- /dev/null
+++ b/proxmox-ve-vfio/debian/debcargo.toml
@@ -0,0 +1,3 @@
+overlay = "."
+crate_src_path = ".."
+maintainer = "Proxmox Support Team <support@proxmox.com>"
diff --git a/proxmox-ve-vfio/generate-nvml-bindings.sh b/proxmox-ve-vfio/generate-nvml-bindings.sh
new file mode 100755
index 0000000..5ea61f7
--- /dev/null
+++ b/proxmox-ve-vfio/generate-nvml-bindings.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+set -o pipefail
+
+cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1
+
+HEADER="${1:-}"
+if [ -z "$HEADER" ]; then
+    echo "Path to nvml.h missing" >&2
+    exit 1
+fi
+
+# We only need a handful of functions, so the bindings can be kept small.
+ALLOWLIST_FN='^nvmlInit_v2|nvmlErrorString|nvmlShutdown|nvmlDeviceGetHandle.*|.*Vgpu.*$'
+ALLOWLIST_VAR='^NVML_.*_BUFFER_SIZE$'
+
+bindgen \
+    --no-doc-comments \
+    --formatter rustfmt \
+    --no-layout-tests \
+    --allowlist-function "$ALLOWLIST_FN" \
+    --allowlist-var "$ALLOWLIST_VAR" \
+    --dynamic-loading NvmlLib \
+    --output src/nvidia/nvml/bindings.rs \
+    "$HEADER"
diff --git a/proxmox-ve-vfio/src/lib.rs b/proxmox-ve-vfio/src/lib.rs
new file mode 100644
index 0000000..a5ef43c
--- /dev/null
+++ b/proxmox-ve-vfio/src/lib.rs
@@ -0,0 +1,6 @@
+//! Exposes an interface for accessing and handling host devices such as NVIDIA vGPU devices, to
+//! e.g. show information about them and prepare them for passthrough.
+
+#![warn(missing_docs)]
+
+pub mod nvidia;
diff --git a/proxmox-ve-vfio/src/nvidia/mod.rs b/proxmox-ve-vfio/src/nvidia/mod.rs
new file mode 100644
index 0000000..08a414c
--- /dev/null
+++ b/proxmox-ve-vfio/src/nvidia/mod.rs
@@ -0,0 +1,3 @@
+//! Provides access to the state of NVIDIA (v)GPU devices connected to the system.
+
+mod nvml;
diff --git a/proxmox-ve-vfio/src/nvidia/nvml/bindings.rs b/proxmox-ve-vfio/src/nvidia/nvml/bindings.rs
new file mode 100644
index 0000000..66617e0
--- /dev/null
+++ b/proxmox-ve-vfio/src/nvidia/nvml/bindings.rs
@@ -0,0 +1,2290 @@
+/* automatically generated by rust-bindgen 0.71.1 */
+
+pub const NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE: u32 = 32;
+pub const NVML_PERF_MODES_BUFFER_SIZE: u32 = 2048;
+pub const NVML_DEVICE_HOSTNAME_BUFFER_SIZE: u32 = 64;
+pub const NVML_GRID_LICENSE_BUFFER_SIZE: u32 = 128;
+pub const NVML_VGPU_NAME_BUFFER_SIZE: u32 = 64;
+pub const NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE: u32 = 16;
+pub const NVML_DEVICE_UUID_BUFFER_SIZE: u32 = 80;
+pub const NVML_DEVICE_UUID_V2_BUFFER_SIZE: u32 = 96;
+pub const NVML_DEVICE_PART_NUMBER_BUFFER_SIZE: u32 = 80;
+pub const NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE: u32 = 80;
+pub const NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE: u32 = 80;
+pub const NVML_DEVICE_NAME_BUFFER_SIZE: u32 = 64;
+pub const NVML_DEVICE_NAME_V2_BUFFER_SIZE: u32 = 96;
+pub const NVML_DEVICE_SERIAL_BUFFER_SIZE: u32 = 30;
+pub const NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE: u32 = 32;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlDevice_st {
+    _unused: [u8; 0],
+}
+pub type nvmlDevice_t = *mut nvmlDevice_st;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlGpuInstance_st {
+    _unused: [u8; 0],
+}
+pub type nvmlGpuInstance_t = *mut nvmlGpuInstance_st;
+pub const nvmlValueType_enum_NVML_VALUE_TYPE_DOUBLE: nvmlValueType_enum = 0;
+pub const nvmlValueType_enum_NVML_VALUE_TYPE_UNSIGNED_INT: nvmlValueType_enum = 1;
+pub const nvmlValueType_enum_NVML_VALUE_TYPE_UNSIGNED_LONG: nvmlValueType_enum = 2;
+pub const nvmlValueType_enum_NVML_VALUE_TYPE_UNSIGNED_LONG_LONG: nvmlValueType_enum = 3;
+pub const nvmlValueType_enum_NVML_VALUE_TYPE_SIGNED_LONG_LONG: nvmlValueType_enum = 4;
+pub const nvmlValueType_enum_NVML_VALUE_TYPE_SIGNED_INT: nvmlValueType_enum = 5;
+pub const nvmlValueType_enum_NVML_VALUE_TYPE_UNSIGNED_SHORT: nvmlValueType_enum = 6;
+pub const nvmlValueType_enum_NVML_VALUE_TYPE_COUNT: nvmlValueType_enum = 7;
+pub type nvmlValueType_enum = ::std::os::raw::c_uint;
+pub use self::nvmlValueType_enum as nvmlValueType_t;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union nvmlValue_st {
+    pub dVal: f64,
+    pub siVal: ::std::os::raw::c_int,
+    pub uiVal: ::std::os::raw::c_uint,
+    pub ulVal: ::std::os::raw::c_ulong,
+    pub ullVal: ::std::os::raw::c_ulonglong,
+    pub sllVal: ::std::os::raw::c_longlong,
+    pub usVal: ::std::os::raw::c_ushort,
+}
+pub type nvmlValue_t = nvmlValue_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union nvmlUUIDValue_t {
+    pub str_: [::std::os::raw::c_char; 41usize],
+    pub bytes: [::std::os::raw::c_uchar; 16usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct nvmlUUID_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub type_: ::std::os::raw::c_uint,
+    pub value: nvmlUUIDValue_t,
+}
+pub type nvmlUUID_t = nvmlUUID_v1_t;
+pub const nvmlEnableState_enum_NVML_FEATURE_DISABLED: nvmlEnableState_enum = 0;
+pub const nvmlEnableState_enum_NVML_FEATURE_ENABLED: nvmlEnableState_enum = 1;
+pub type nvmlEnableState_enum = ::std::os::raw::c_uint;
+pub use self::nvmlEnableState_enum as nvmlEnableState_t;
+pub const nvmlReturn_enum_NVML_SUCCESS: nvmlReturn_enum = 0;
+pub const nvmlReturn_enum_NVML_ERROR_UNINITIALIZED: nvmlReturn_enum = 1;
+pub const nvmlReturn_enum_NVML_ERROR_INVALID_ARGUMENT: nvmlReturn_enum = 2;
+pub const nvmlReturn_enum_NVML_ERROR_NOT_SUPPORTED: nvmlReturn_enum = 3;
+pub const nvmlReturn_enum_NVML_ERROR_NO_PERMISSION: nvmlReturn_enum = 4;
+pub const nvmlReturn_enum_NVML_ERROR_ALREADY_INITIALIZED: nvmlReturn_enum = 5;
+pub const nvmlReturn_enum_NVML_ERROR_NOT_FOUND: nvmlReturn_enum = 6;
+pub const nvmlReturn_enum_NVML_ERROR_INSUFFICIENT_SIZE: nvmlReturn_enum = 7;
+pub const nvmlReturn_enum_NVML_ERROR_INSUFFICIENT_POWER: nvmlReturn_enum = 8;
+pub const nvmlReturn_enum_NVML_ERROR_DRIVER_NOT_LOADED: nvmlReturn_enum = 9;
+pub const nvmlReturn_enum_NVML_ERROR_TIMEOUT: nvmlReturn_enum = 10;
+pub const nvmlReturn_enum_NVML_ERROR_IRQ_ISSUE: nvmlReturn_enum = 11;
+pub const nvmlReturn_enum_NVML_ERROR_LIBRARY_NOT_FOUND: nvmlReturn_enum = 12;
+pub const nvmlReturn_enum_NVML_ERROR_FUNCTION_NOT_FOUND: nvmlReturn_enum = 13;
+pub const nvmlReturn_enum_NVML_ERROR_CORRUPTED_INFOROM: nvmlReturn_enum = 14;
+pub const nvmlReturn_enum_NVML_ERROR_GPU_IS_LOST: nvmlReturn_enum = 15;
+pub const nvmlReturn_enum_NVML_ERROR_RESET_REQUIRED: nvmlReturn_enum = 16;
+pub const nvmlReturn_enum_NVML_ERROR_OPERATING_SYSTEM: nvmlReturn_enum = 17;
+pub const nvmlReturn_enum_NVML_ERROR_LIB_RM_VERSION_MISMATCH: nvmlReturn_enum = 18;
+pub const nvmlReturn_enum_NVML_ERROR_IN_USE: nvmlReturn_enum = 19;
+pub const nvmlReturn_enum_NVML_ERROR_MEMORY: nvmlReturn_enum = 20;
+pub const nvmlReturn_enum_NVML_ERROR_NO_DATA: nvmlReturn_enum = 21;
+pub const nvmlReturn_enum_NVML_ERROR_VGPU_ECC_NOT_SUPPORTED: nvmlReturn_enum = 22;
+pub const nvmlReturn_enum_NVML_ERROR_INSUFFICIENT_RESOURCES: nvmlReturn_enum = 23;
+pub const nvmlReturn_enum_NVML_ERROR_FREQ_NOT_SUPPORTED: nvmlReturn_enum = 24;
+pub const nvmlReturn_enum_NVML_ERROR_ARGUMENT_VERSION_MISMATCH: nvmlReturn_enum = 25;
+pub const nvmlReturn_enum_NVML_ERROR_DEPRECATED: nvmlReturn_enum = 26;
+pub const nvmlReturn_enum_NVML_ERROR_NOT_READY: nvmlReturn_enum = 27;
+pub const nvmlReturn_enum_NVML_ERROR_GPU_NOT_FOUND: nvmlReturn_enum = 28;
+pub const nvmlReturn_enum_NVML_ERROR_INVALID_STATE: nvmlReturn_enum = 29;
+pub const nvmlReturn_enum_NVML_ERROR_RESET_TYPE_NOT_SUPPORTED: nvmlReturn_enum = 30;
+pub const nvmlReturn_enum_NVML_ERROR_UNKNOWN: nvmlReturn_enum = 999;
+pub type nvmlReturn_enum = ::std::os::raw::c_uint;
+pub use self::nvmlReturn_enum as nvmlReturn_t;
+pub const nvmlHostVgpuMode_enum_NVML_HOST_VGPU_MODE_NON_SRIOV: nvmlHostVgpuMode_enum = 0;
+pub const nvmlHostVgpuMode_enum_NVML_HOST_VGPU_MODE_SRIOV: nvmlHostVgpuMode_enum = 1;
+pub type nvmlHostVgpuMode_enum = ::std::os::raw::c_uint;
+pub use self::nvmlHostVgpuMode_enum as nvmlHostVgpuMode_t;
+pub const nvmlVgpuVmIdType_NVML_VGPU_VM_ID_DOMAIN_ID: nvmlVgpuVmIdType = 0;
+pub const nvmlVgpuVmIdType_NVML_VGPU_VM_ID_UUID: nvmlVgpuVmIdType = 1;
+pub type nvmlVgpuVmIdType = ::std::os::raw::c_uint;
+pub use self::nvmlVgpuVmIdType as nvmlVgpuVmIdType_t;
+pub const nvmlVgpuGuestInfoState_enum_NVML_VGPU_INSTANCE_GUEST_INFO_STATE_UNINITIALIZED:
+    nvmlVgpuGuestInfoState_enum = 0;
+pub const nvmlVgpuGuestInfoState_enum_NVML_VGPU_INSTANCE_GUEST_INFO_STATE_INITIALIZED:
+    nvmlVgpuGuestInfoState_enum = 1;
+pub type nvmlVgpuGuestInfoState_enum = ::std::os::raw::c_uint;
+pub use self::nvmlVgpuGuestInfoState_enum as nvmlVgpuGuestInfoState_t;
+pub const nvmlVgpuCapability_enum_NVML_VGPU_CAP_NVLINK_P2P: nvmlVgpuCapability_enum = 0;
+pub const nvmlVgpuCapability_enum_NVML_VGPU_CAP_GPUDIRECT: nvmlVgpuCapability_enum = 1;
+pub const nvmlVgpuCapability_enum_NVML_VGPU_CAP_MULTI_VGPU_EXCLUSIVE: nvmlVgpuCapability_enum = 2;
+pub const nvmlVgpuCapability_enum_NVML_VGPU_CAP_EXCLUSIVE_TYPE: nvmlVgpuCapability_enum = 3;
+pub const nvmlVgpuCapability_enum_NVML_VGPU_CAP_EXCLUSIVE_SIZE: nvmlVgpuCapability_enum = 4;
+pub const nvmlVgpuCapability_enum_NVML_VGPU_CAP_COUNT: nvmlVgpuCapability_enum = 5;
+pub type nvmlVgpuCapability_enum = ::std::os::raw::c_uint;
+pub use self::nvmlVgpuCapability_enum as nvmlVgpuCapability_t;
+pub const nvmlVgpuDriverCapability_enum_NVML_VGPU_DRIVER_CAP_HETEROGENEOUS_MULTI_VGPU:
+    nvmlVgpuDriverCapability_enum = 0;
+pub const nvmlVgpuDriverCapability_enum_NVML_VGPU_DRIVER_CAP_WARM_UPDATE:
+    nvmlVgpuDriverCapability_enum = 1;
+pub const nvmlVgpuDriverCapability_enum_NVML_VGPU_DRIVER_CAP_COUNT: nvmlVgpuDriverCapability_enum =
+    2;
+pub type nvmlVgpuDriverCapability_enum = ::std::os::raw::c_uint;
+pub use self::nvmlVgpuDriverCapability_enum as nvmlVgpuDriverCapability_t;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_FRACTIONAL_MULTI_VGPU:
+    nvmlDeviceVgpuCapability_enum = 0;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_PROFILES:
+    nvmlDeviceVgpuCapability_enum = 1;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_SIZES:
+    nvmlDeviceVgpuCapability_enum = 2;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_READ_DEVICE_BUFFER_BW:
+    nvmlDeviceVgpuCapability_enum = 3;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_WRITE_DEVICE_BUFFER_BW:
+    nvmlDeviceVgpuCapability_enum = 4;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_DEVICE_STREAMING:
+    nvmlDeviceVgpuCapability_enum = 5;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_MINI_QUARTER_GPU:
+    nvmlDeviceVgpuCapability_enum = 6;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_COMPUTE_MEDIA_ENGINE_GPU:
+    nvmlDeviceVgpuCapability_enum = 7;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_WARM_UPDATE:
+    nvmlDeviceVgpuCapability_enum = 8;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_HOMOGENEOUS_PLACEMENTS:
+    nvmlDeviceVgpuCapability_enum = 9;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_MIG_TIMESLICING_SUPPORTED:
+    nvmlDeviceVgpuCapability_enum = 10;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_MIG_TIMESLICING_ENABLED:
+    nvmlDeviceVgpuCapability_enum = 11;
+pub const nvmlDeviceVgpuCapability_enum_NVML_DEVICE_VGPU_CAP_COUNT: nvmlDeviceVgpuCapability_enum =
+    12;
+pub type nvmlDeviceVgpuCapability_enum = ::std::os::raw::c_uint;
+pub use self::nvmlDeviceVgpuCapability_enum as nvmlDeviceVgpuCapability_t;
+pub type nvmlVgpuTypeId_t = ::std::os::raw::c_uint;
+pub type nvmlVgpuInstance_t = ::std::os::raw::c_uint;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuHeterogeneousMode_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub mode: ::std::os::raw::c_uint,
+}
+pub type nvmlVgpuHeterogeneousMode_t = nvmlVgpuHeterogeneousMode_v1_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuPlacementId_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub placementId: ::std::os::raw::c_uint,
+}
+pub type nvmlVgpuPlacementId_t = nvmlVgpuPlacementId_v1_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuPlacementList_v2_t {
+    pub version: ::std::os::raw::c_uint,
+    pub placementSize: ::std::os::raw::c_uint,
+    pub count: ::std::os::raw::c_uint,
+    pub placementIds: *mut ::std::os::raw::c_uint,
+    pub mode: ::std::os::raw::c_uint,
+}
+pub type nvmlVgpuPlacementList_t = nvmlVgpuPlacementList_v2_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuTypeBar1Info_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub bar1Size: ::std::os::raw::c_ulonglong,
+}
+pub type nvmlVgpuTypeBar1Info_t = nvmlVgpuTypeBar1Info_v1_t;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct nvmlVgpuInstanceUtilizationSample_st {
+    pub vgpuInstance: nvmlVgpuInstance_t,
+    pub timeStamp: ::std::os::raw::c_ulonglong,
+    pub smUtil: nvmlValue_t,
+    pub memUtil: nvmlValue_t,
+    pub encUtil: nvmlValue_t,
+    pub decUtil: nvmlValue_t,
+}
+pub type nvmlVgpuInstanceUtilizationSample_t = nvmlVgpuInstanceUtilizationSample_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct nvmlVgpuInstanceUtilizationInfo_v1_t {
+    pub timeStamp: ::std::os::raw::c_ulonglong,
+    pub vgpuInstance: nvmlVgpuInstance_t,
+    pub smUtil: nvmlValue_t,
+    pub memUtil: nvmlValue_t,
+    pub encUtil: nvmlValue_t,
+    pub decUtil: nvmlValue_t,
+    pub jpgUtil: nvmlValue_t,
+    pub ofaUtil: nvmlValue_t,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuInstancesUtilizationInfo_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub sampleValType: nvmlValueType_t,
+    pub vgpuInstanceCount: ::std::os::raw::c_uint,
+    pub lastSeenTimeStamp: ::std::os::raw::c_ulonglong,
+    pub vgpuUtilArray: *mut nvmlVgpuInstanceUtilizationInfo_v1_t,
+}
+pub type nvmlVgpuInstancesUtilizationInfo_t = nvmlVgpuInstancesUtilizationInfo_v1_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuProcessUtilizationSample_st {
+    pub vgpuInstance: nvmlVgpuInstance_t,
+    pub pid: ::std::os::raw::c_uint,
+    pub processName: [::std::os::raw::c_char; 64usize],
+    pub timeStamp: ::std::os::raw::c_ulonglong,
+    pub smUtil: ::std::os::raw::c_uint,
+    pub memUtil: ::std::os::raw::c_uint,
+    pub encUtil: ::std::os::raw::c_uint,
+    pub decUtil: ::std::os::raw::c_uint,
+}
+pub type nvmlVgpuProcessUtilizationSample_t = nvmlVgpuProcessUtilizationSample_st;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuProcessUtilizationInfo_v1_t {
+    pub processName: [::std::os::raw::c_char; 64usize],
+    pub timeStamp: ::std::os::raw::c_ulonglong,
+    pub vgpuInstance: nvmlVgpuInstance_t,
+    pub pid: ::std::os::raw::c_uint,
+    pub smUtil: ::std::os::raw::c_uint,
+    pub memUtil: ::std::os::raw::c_uint,
+    pub encUtil: ::std::os::raw::c_uint,
+    pub decUtil: ::std::os::raw::c_uint,
+    pub jpgUtil: ::std::os::raw::c_uint,
+    pub ofaUtil: ::std::os::raw::c_uint,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuProcessesUtilizationInfo_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub vgpuProcessCount: ::std::os::raw::c_uint,
+    pub lastSeenTimeStamp: ::std::os::raw::c_ulonglong,
+    pub vgpuProcUtilArray: *mut nvmlVgpuProcessUtilizationInfo_v1_t,
+}
+pub type nvmlVgpuProcessesUtilizationInfo_t = nvmlVgpuProcessesUtilizationInfo_v1_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuRuntimeState_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub size: ::std::os::raw::c_ulonglong,
+}
+pub type nvmlVgpuRuntimeState_t = nvmlVgpuRuntimeState_v1_t;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union nvmlVgpuSchedulerParams_t {
+    pub vgpuSchedDataWithARR: nvmlVgpuSchedulerParams_t__bindgen_ty_1,
+    pub vgpuSchedData: nvmlVgpuSchedulerParams_t__bindgen_ty_2,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuSchedulerParams_t__bindgen_ty_1 {
+    pub avgFactor: ::std::os::raw::c_uint,
+    pub timeslice: ::std::os::raw::c_uint,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuSchedulerParams_t__bindgen_ty_2 {
+    pub timeslice: ::std::os::raw::c_uint,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuSchedulerLogEntries_st {
+    pub timestamp: ::std::os::raw::c_ulonglong,
+    pub timeRunTotal: ::std::os::raw::c_ulonglong,
+    pub timeRun: ::std::os::raw::c_ulonglong,
+    pub swRunlistId: ::std::os::raw::c_uint,
+    pub targetTimeSlice: ::std::os::raw::c_ulonglong,
+    pub cumulativePreemptionTime: ::std::os::raw::c_ulonglong,
+}
+pub type nvmlVgpuSchedulerLogEntry_t = nvmlVgpuSchedulerLogEntries_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct nvmlVgpuSchedulerLog_st {
+    pub engineId: ::std::os::raw::c_uint,
+    pub schedulerPolicy: ::std::os::raw::c_uint,
+    pub arrMode: ::std::os::raw::c_uint,
+    pub schedulerParams: nvmlVgpuSchedulerParams_t,
+    pub entriesCount: ::std::os::raw::c_uint,
+    pub logEntries: [nvmlVgpuSchedulerLogEntry_t; 200usize],
+}
+pub type nvmlVgpuSchedulerLog_t = nvmlVgpuSchedulerLog_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct nvmlVgpuSchedulerGetState_st {
+    pub schedulerPolicy: ::std::os::raw::c_uint,
+    pub arrMode: ::std::os::raw::c_uint,
+    pub schedulerParams: nvmlVgpuSchedulerParams_t,
+}
+pub type nvmlVgpuSchedulerGetState_t = nvmlVgpuSchedulerGetState_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union nvmlVgpuSchedulerSetParams_t {
+    pub vgpuSchedDataWithARR: nvmlVgpuSchedulerSetParams_t__bindgen_ty_1,
+    pub vgpuSchedData: nvmlVgpuSchedulerSetParams_t__bindgen_ty_2,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuSchedulerSetParams_t__bindgen_ty_1 {
+    pub avgFactor: ::std::os::raw::c_uint,
+    pub frequency: ::std::os::raw::c_uint,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuSchedulerSetParams_t__bindgen_ty_2 {
+    pub timeslice: ::std::os::raw::c_uint,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct nvmlVgpuSchedulerSetState_st {
+    pub schedulerPolicy: ::std::os::raw::c_uint,
+    pub enableARRMode: ::std::os::raw::c_uint,
+    pub schedulerParams: nvmlVgpuSchedulerSetParams_t,
+}
+pub type nvmlVgpuSchedulerSetState_t = nvmlVgpuSchedulerSetState_st;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuSchedulerCapabilities_st {
+    pub supportedSchedulers: [::std::os::raw::c_uint; 3usize],
+    pub maxTimeslice: ::std::os::raw::c_uint,
+    pub minTimeslice: ::std::os::raw::c_uint,
+    pub isArrModeSupported: ::std::os::raw::c_uint,
+    pub maxFrequencyForARR: ::std::os::raw::c_uint,
+    pub minFrequencyForARR: ::std::os::raw::c_uint,
+    pub maxAvgFactorForARR: ::std::os::raw::c_uint,
+    pub minAvgFactorForARR: ::std::os::raw::c_uint,
+}
+pub type nvmlVgpuSchedulerCapabilities_t = nvmlVgpuSchedulerCapabilities_st;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuLicenseExpiry_st {
+    pub year: ::std::os::raw::c_uint,
+    pub month: ::std::os::raw::c_ushort,
+    pub day: ::std::os::raw::c_ushort,
+    pub hour: ::std::os::raw::c_ushort,
+    pub min: ::std::os::raw::c_ushort,
+    pub sec: ::std::os::raw::c_ushort,
+    pub status: ::std::os::raw::c_uchar,
+}
+pub type nvmlVgpuLicenseExpiry_t = nvmlVgpuLicenseExpiry_st;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuLicenseInfo_st {
+    pub isLicensed: ::std::os::raw::c_uchar,
+    pub licenseExpiry: nvmlVgpuLicenseExpiry_t,
+    pub currentState: ::std::os::raw::c_uint,
+}
+pub type nvmlVgpuLicenseInfo_t = nvmlVgpuLicenseInfo_st;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuTypeIdInfo_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub vgpuCount: ::std::os::raw::c_uint,
+    pub vgpuTypeIds: *mut nvmlVgpuTypeId_t,
+}
+pub type nvmlVgpuTypeIdInfo_t = nvmlVgpuTypeIdInfo_v1_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuTypeMaxInstance_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub vgpuTypeId: nvmlVgpuTypeId_t,
+    pub maxInstancePerGI: ::std::os::raw::c_uint,
+}
+pub type nvmlVgpuTypeMaxInstance_t = nvmlVgpuTypeMaxInstance_v1_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlActiveVgpuInstanceInfo_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub vgpuCount: ::std::os::raw::c_uint,
+    pub vgpuInstances: *mut nvmlVgpuInstance_t,
+}
+pub type nvmlActiveVgpuInstanceInfo_t = nvmlActiveVgpuInstanceInfo_v1_t;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct nvmlVgpuSchedulerState_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub engineId: ::std::os::raw::c_uint,
+    pub schedulerPolicy: ::std::os::raw::c_uint,
+    pub enableARRMode: ::std::os::raw::c_uint,
+    pub schedulerParams: nvmlVgpuSchedulerSetParams_t,
+}
+pub type nvmlVgpuSchedulerState_t = nvmlVgpuSchedulerState_v1_t;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct nvmlVgpuSchedulerStateInfo_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub engineId: ::std::os::raw::c_uint,
+    pub schedulerPolicy: ::std::os::raw::c_uint,
+    pub arrMode: ::std::os::raw::c_uint,
+    pub schedulerParams: nvmlVgpuSchedulerParams_t,
+}
+pub type nvmlVgpuSchedulerStateInfo_t = nvmlVgpuSchedulerStateInfo_v1_t;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct nvmlVgpuSchedulerLogInfo_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub engineId: ::std::os::raw::c_uint,
+    pub schedulerPolicy: ::std::os::raw::c_uint,
+    pub arrMode: ::std::os::raw::c_uint,
+    pub schedulerParams: nvmlVgpuSchedulerParams_t,
+    pub entriesCount: ::std::os::raw::c_uint,
+    pub logEntries: [nvmlVgpuSchedulerLogEntry_t; 200usize],
+}
+pub type nvmlVgpuSchedulerLogInfo_t = nvmlVgpuSchedulerLogInfo_v1_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuCreatablePlacementInfo_v1_t {
+    pub version: ::std::os::raw::c_uint,
+    pub vgpuTypeId: nvmlVgpuTypeId_t,
+    pub count: ::std::os::raw::c_uint,
+    pub placementIds: *mut ::std::os::raw::c_uint,
+    pub placementSize: ::std::os::raw::c_uint,
+}
+pub type nvmlVgpuCreatablePlacementInfo_t = nvmlVgpuCreatablePlacementInfo_v1_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlAccountingStats_st {
+    pub gpuUtilization: ::std::os::raw::c_uint,
+    pub memoryUtilization: ::std::os::raw::c_uint,
+    pub maxMemoryUsage: ::std::os::raw::c_ulonglong,
+    pub time: ::std::os::raw::c_ulonglong,
+    pub startTime: ::std::os::raw::c_ulonglong,
+    pub isRunning: ::std::os::raw::c_uint,
+    pub reserved: [::std::os::raw::c_uint; 5usize],
+}
+pub type nvmlAccountingStats_t = nvmlAccountingStats_st;
+pub const nvmlEncoderQueryType_enum_NVML_ENCODER_QUERY_H264: nvmlEncoderQueryType_enum = 0;
+pub const nvmlEncoderQueryType_enum_NVML_ENCODER_QUERY_HEVC: nvmlEncoderQueryType_enum = 1;
+pub const nvmlEncoderQueryType_enum_NVML_ENCODER_QUERY_AV1: nvmlEncoderQueryType_enum = 2;
+pub const nvmlEncoderQueryType_enum_NVML_ENCODER_QUERY_UNKNOWN: nvmlEncoderQueryType_enum = 255;
+pub type nvmlEncoderQueryType_enum = ::std::os::raw::c_uint;
+pub use self::nvmlEncoderQueryType_enum as nvmlEncoderType_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlEncoderSessionInfo_st {
+    pub sessionId: ::std::os::raw::c_uint,
+    pub pid: ::std::os::raw::c_uint,
+    pub vgpuInstance: nvmlVgpuInstance_t,
+    pub codecType: nvmlEncoderType_t,
+    pub hResolution: ::std::os::raw::c_uint,
+    pub vResolution: ::std::os::raw::c_uint,
+    pub averageFps: ::std::os::raw::c_uint,
+    pub averageLatency: ::std::os::raw::c_uint,
+}
+pub type nvmlEncoderSessionInfo_t = nvmlEncoderSessionInfo_st;
+pub const nvmlFBCSessionType_enum_NVML_FBC_SESSION_TYPE_UNKNOWN: nvmlFBCSessionType_enum = 0;
+pub const nvmlFBCSessionType_enum_NVML_FBC_SESSION_TYPE_TOSYS: nvmlFBCSessionType_enum = 1;
+pub const nvmlFBCSessionType_enum_NVML_FBC_SESSION_TYPE_CUDA: nvmlFBCSessionType_enum = 2;
+pub const nvmlFBCSessionType_enum_NVML_FBC_SESSION_TYPE_VID: nvmlFBCSessionType_enum = 3;
+pub const nvmlFBCSessionType_enum_NVML_FBC_SESSION_TYPE_HWENC: nvmlFBCSessionType_enum = 4;
+pub type nvmlFBCSessionType_enum = ::std::os::raw::c_uint;
+pub use self::nvmlFBCSessionType_enum as nvmlFBCSessionType_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlFBCStats_st {
+    pub sessionsCount: ::std::os::raw::c_uint,
+    pub averageFPS: ::std::os::raw::c_uint,
+    pub averageLatency: ::std::os::raw::c_uint,
+}
+pub type nvmlFBCStats_t = nvmlFBCStats_st;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlFBCSessionInfo_st {
+    pub sessionId: ::std::os::raw::c_uint,
+    pub pid: ::std::os::raw::c_uint,
+    pub vgpuInstance: nvmlVgpuInstance_t,
+    pub displayOrdinal: ::std::os::raw::c_uint,
+    pub sessionType: nvmlFBCSessionType_t,
+    pub sessionFlags: ::std::os::raw::c_uint,
+    pub hMaxResolution: ::std::os::raw::c_uint,
+    pub vMaxResolution: ::std::os::raw::c_uint,
+    pub hResolution: ::std::os::raw::c_uint,
+    pub vResolution: ::std::os::raw::c_uint,
+    pub averageFPS: ::std::os::raw::c_uint,
+    pub averageLatency: ::std::os::raw::c_uint,
+}
+pub type nvmlFBCSessionInfo_t = nvmlFBCSessionInfo_st;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuVersion_st {
+    pub minVersion: ::std::os::raw::c_uint,
+    pub maxVersion: ::std::os::raw::c_uint,
+}
+pub type nvmlVgpuVersion_t = nvmlVgpuVersion_st;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuMetadata_st {
+    pub version: ::std::os::raw::c_uint,
+    pub revision: ::std::os::raw::c_uint,
+    pub guestInfoState: nvmlVgpuGuestInfoState_t,
+    pub guestDriverVersion: [::std::os::raw::c_char; 80usize],
+    pub hostDriverVersion: [::std::os::raw::c_char; 80usize],
+    pub reserved: [::std::os::raw::c_uint; 6usize],
+    pub vgpuVirtualizationCaps: ::std::os::raw::c_uint,
+    pub guestVgpuVersion: ::std::os::raw::c_uint,
+    pub opaqueDataSize: ::std::os::raw::c_uint,
+    pub opaqueData: [::std::os::raw::c_char; 4usize],
+}
+pub type nvmlVgpuMetadata_t = nvmlVgpuMetadata_st;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuPgpuMetadata_st {
+    pub version: ::std::os::raw::c_uint,
+    pub revision: ::std::os::raw::c_uint,
+    pub hostDriverVersion: [::std::os::raw::c_char; 80usize],
+    pub pgpuVirtualizationCaps: ::std::os::raw::c_uint,
+    pub reserved: [::std::os::raw::c_uint; 5usize],
+    pub hostSupportedVgpuRange: nvmlVgpuVersion_t,
+    pub opaqueDataSize: ::std::os::raw::c_uint,
+    pub opaqueData: [::std::os::raw::c_char; 4usize],
+}
+pub type nvmlVgpuPgpuMetadata_t = nvmlVgpuPgpuMetadata_st;
+pub const nvmlVgpuVmCompatibility_enum_NVML_VGPU_VM_COMPATIBILITY_NONE:
+    nvmlVgpuVmCompatibility_enum = 0;
+pub const nvmlVgpuVmCompatibility_enum_NVML_VGPU_VM_COMPATIBILITY_COLD:
+    nvmlVgpuVmCompatibility_enum = 1;
+pub const nvmlVgpuVmCompatibility_enum_NVML_VGPU_VM_COMPATIBILITY_HIBERNATE:
+    nvmlVgpuVmCompatibility_enum = 2;
+pub const nvmlVgpuVmCompatibility_enum_NVML_VGPU_VM_COMPATIBILITY_SLEEP:
+    nvmlVgpuVmCompatibility_enum = 4;
+pub const nvmlVgpuVmCompatibility_enum_NVML_VGPU_VM_COMPATIBILITY_LIVE:
+    nvmlVgpuVmCompatibility_enum = 8;
+pub type nvmlVgpuVmCompatibility_enum = ::std::os::raw::c_uint;
+pub use self::nvmlVgpuVmCompatibility_enum as nvmlVgpuVmCompatibility_t;
+pub const nvmlVgpuPgpuCompatibilityLimitCode_enum_NVML_VGPU_COMPATIBILITY_LIMIT_NONE:
+    nvmlVgpuPgpuCompatibilityLimitCode_enum = 0;
+pub const nvmlVgpuPgpuCompatibilityLimitCode_enum_NVML_VGPU_COMPATIBILITY_LIMIT_HOST_DRIVER:
+    nvmlVgpuPgpuCompatibilityLimitCode_enum = 1;
+pub const nvmlVgpuPgpuCompatibilityLimitCode_enum_NVML_VGPU_COMPATIBILITY_LIMIT_GUEST_DRIVER:
+    nvmlVgpuPgpuCompatibilityLimitCode_enum = 2;
+pub const nvmlVgpuPgpuCompatibilityLimitCode_enum_NVML_VGPU_COMPATIBILITY_LIMIT_GPU:
+    nvmlVgpuPgpuCompatibilityLimitCode_enum = 4;
+pub const nvmlVgpuPgpuCompatibilityLimitCode_enum_NVML_VGPU_COMPATIBILITY_LIMIT_OTHER:
+    nvmlVgpuPgpuCompatibilityLimitCode_enum = 2147483648;
+pub type nvmlVgpuPgpuCompatibilityLimitCode_enum = ::std::os::raw::c_uint;
+pub use self::nvmlVgpuPgpuCompatibilityLimitCode_enum as nvmlVgpuPgpuCompatibilityLimitCode_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct nvmlVgpuPgpuCompatibility_st {
+    pub vgpuVmCompatibility: nvmlVgpuVmCompatibility_t,
+    pub compatibilityLimitCode: nvmlVgpuPgpuCompatibilityLimitCode_t,
+}
+pub type nvmlVgpuPgpuCompatibility_t = nvmlVgpuPgpuCompatibility_st;
+pub struct NvmlLib {
+    __library: ::libloading::Library,
+    pub nvmlInit_v2: Result<unsafe extern "C" fn() -> nvmlReturn_t, ::libloading::Error>,
+    pub nvmlShutdown: Result<unsafe extern "C" fn() -> nvmlReturn_t, ::libloading::Error>,
+    pub nvmlErrorString: Result<
+        unsafe extern "C" fn(result: nvmlReturn_t) -> *const ::std::os::raw::c_char,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetHandleByIndex_v2: Result<
+        unsafe extern "C" fn(
+            index: ::std::os::raw::c_uint,
+            device: *mut nvmlDevice_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetHandleBySerial: Result<
+        unsafe extern "C" fn(
+            serial: *const ::std::os::raw::c_char,
+            device: *mut nvmlDevice_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetHandleByUUID: Result<
+        unsafe extern "C" fn(
+            uuid: *const ::std::os::raw::c_char,
+            device: *mut nvmlDevice_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetHandleByUUIDV: Result<
+        unsafe extern "C" fn(uuid: *const nvmlUUID_t, device: *mut nvmlDevice_t) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetHandleByPciBusId_v2: Result<
+        unsafe extern "C" fn(
+            pciBusId: *const ::std::os::raw::c_char,
+            device: *mut nvmlDevice_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetHostVgpuMode: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            pHostVgpuMode: *mut nvmlHostVgpuMode_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuHeterogeneousMode: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            pHeterogeneousMode: *mut nvmlVgpuHeterogeneousMode_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceSetVgpuHeterogeneousMode: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            pHeterogeneousMode: *const nvmlVgpuHeterogeneousMode_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetPlacementId: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            pPlacement: *mut nvmlVgpuPlacementId_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuTypeSupportedPlacements: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            pPlacementList: *mut nvmlVgpuPlacementList_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuTypeCreatablePlacements: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            pPlacementList: *mut nvmlVgpuPlacementList_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetGspHeapSize: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            gspHeapSize: *mut ::std::os::raw::c_ulonglong,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetFbReservation: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            fbReservation: *mut ::std::os::raw::c_ulonglong,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetRuntimeStateSize: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            pState: *mut nvmlVgpuRuntimeState_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceSetVgpuCapabilities: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            capability: nvmlDeviceVgpuCapability_t,
+            state: nvmlEnableState_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGetVgpuDriverCapabilities: Result<
+        unsafe extern "C" fn(
+            capability: nvmlVgpuDriverCapability_t,
+            capResult: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuCapabilities: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            capability: nvmlDeviceVgpuCapability_t,
+            capResult: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetSupportedVgpus: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            vgpuCount: *mut ::std::os::raw::c_uint,
+            vgpuTypeIds: *mut nvmlVgpuTypeId_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetCreatableVgpus: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            vgpuCount: *mut ::std::os::raw::c_uint,
+            vgpuTypeIds: *mut nvmlVgpuTypeId_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetClass: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            vgpuTypeClass: *mut ::std::os::raw::c_char,
+            size: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetName: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            vgpuTypeName: *mut ::std::os::raw::c_char,
+            size: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetGpuInstanceProfileId: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            gpuInstanceProfileId: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetDeviceID: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            deviceID: *mut ::std::os::raw::c_ulonglong,
+            subsystemID: *mut ::std::os::raw::c_ulonglong,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetFramebufferSize: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            fbSize: *mut ::std::os::raw::c_ulonglong,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetNumDisplayHeads: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            numDisplayHeads: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetResolution: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            displayIndex: ::std::os::raw::c_uint,
+            xdim: *mut ::std::os::raw::c_uint,
+            ydim: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetLicense: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            vgpuTypeLicenseString: *mut ::std::os::raw::c_char,
+            size: ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetFrameRateLimit: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            frameRateLimit: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetMaxInstances: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            vgpuInstanceCount: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetMaxInstancesPerVm: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            vgpuInstanceCountPerVm: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetBAR1Info: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            bar1Info: *mut nvmlVgpuTypeBar1Info_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetActiveVgpus: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            vgpuCount: *mut ::std::os::raw::c_uint,
+            vgpuInstances: *mut nvmlVgpuInstance_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetVmID: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            vmId: *mut ::std::os::raw::c_char,
+            size: ::std::os::raw::c_uint,
+            vmIdType: *mut nvmlVgpuVmIdType_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetUUID: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            uuid: *mut ::std::os::raw::c_char,
+            size: ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetVmDriverVersion: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            version: *mut ::std::os::raw::c_char,
+            length: ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetFbUsage: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            fbUsage: *mut ::std::os::raw::c_ulonglong,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetLicenseStatus: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            licensed: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetType: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            vgpuTypeId: *mut nvmlVgpuTypeId_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetFrameRateLimit: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            frameRateLimit: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetEccMode: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            eccMode: *mut nvmlEnableState_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetEncoderCapacity: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            encoderCapacity: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceSetEncoderCapacity: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            encoderCapacity: ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetEncoderStats: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            sessionCount: *mut ::std::os::raw::c_uint,
+            averageFps: *mut ::std::os::raw::c_uint,
+            averageLatency: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetEncoderSessions: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            sessionCount: *mut ::std::os::raw::c_uint,
+            sessionInfo: *mut nvmlEncoderSessionInfo_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetFBCStats: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            fbcStats: *mut nvmlFBCStats_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetFBCSessions: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            sessionCount: *mut ::std::os::raw::c_uint,
+            sessionInfo: *mut nvmlFBCSessionInfo_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetGpuInstanceId: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            gpuInstanceId: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetGpuPciId: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            vgpuPciId: *mut ::std::os::raw::c_char,
+            length: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetCapabilities: Result<
+        unsafe extern "C" fn(
+            vgpuTypeId: nvmlVgpuTypeId_t,
+            capability: nvmlVgpuCapability_t,
+            capResult: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetMdevUUID: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            mdevUuid: *mut ::std::os::raw::c_char,
+            size: ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGpuInstanceGetCreatableVgpus: Result<
+        unsafe extern "C" fn(
+            gpuInstance: nvmlGpuInstance_t,
+            pVgpus: *mut nvmlVgpuTypeIdInfo_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuTypeGetMaxInstancesPerGpuInstance: Result<
+        unsafe extern "C" fn(pMaxInstance: *mut nvmlVgpuTypeMaxInstance_t) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGpuInstanceGetActiveVgpus: Result<
+        unsafe extern "C" fn(
+            gpuInstance: nvmlGpuInstance_t,
+            pVgpuInstanceInfo: *mut nvmlActiveVgpuInstanceInfo_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGpuInstanceSetVgpuSchedulerState: Result<
+        unsafe extern "C" fn(
+            gpuInstance: nvmlGpuInstance_t,
+            pScheduler: *mut nvmlVgpuSchedulerState_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGpuInstanceGetVgpuSchedulerState: Result<
+        unsafe extern "C" fn(
+            gpuInstance: nvmlGpuInstance_t,
+            pSchedulerStateInfo: *mut nvmlVgpuSchedulerStateInfo_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGpuInstanceGetVgpuSchedulerLog: Result<
+        unsafe extern "C" fn(
+            gpuInstance: nvmlGpuInstance_t,
+            pSchedulerLogInfo: *mut nvmlVgpuSchedulerLogInfo_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGpuInstanceGetVgpuTypeCreatablePlacements: Result<
+        unsafe extern "C" fn(
+            gpuInstance: nvmlGpuInstance_t,
+            pCreatablePlacementInfo: *mut nvmlVgpuCreatablePlacementInfo_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGpuInstanceGetVgpuHeterogeneousMode: Result<
+        unsafe extern "C" fn(
+            gpuInstance: nvmlGpuInstance_t,
+            pHeterogeneousMode: *mut nvmlVgpuHeterogeneousMode_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGpuInstanceSetVgpuHeterogeneousMode: Result<
+        unsafe extern "C" fn(
+            gpuInstance: nvmlGpuInstance_t,
+            pHeterogeneousMode: *const nvmlVgpuHeterogeneousMode_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetMetadata: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            vgpuMetadata: *mut nvmlVgpuMetadata_t,
+            bufferSize: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuMetadata: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            pgpuMetadata: *mut nvmlVgpuPgpuMetadata_t,
+            bufferSize: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGetVgpuCompatibility: Result<
+        unsafe extern "C" fn(
+            vgpuMetadata: *mut nvmlVgpuMetadata_t,
+            pgpuMetadata: *mut nvmlVgpuPgpuMetadata_t,
+            compatibilityInfo: *mut nvmlVgpuPgpuCompatibility_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuSchedulerLog: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            pSchedulerLog: *mut nvmlVgpuSchedulerLog_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuSchedulerState: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            pSchedulerState: *mut nvmlVgpuSchedulerGetState_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuSchedulerCapabilities: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            pCapabilities: *mut nvmlVgpuSchedulerCapabilities_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceSetVgpuSchedulerState: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            pSchedulerState: *mut nvmlVgpuSchedulerSetState_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlGetVgpuVersion: Result<
+        unsafe extern "C" fn(
+            supported: *mut nvmlVgpuVersion_t,
+            current: *mut nvmlVgpuVersion_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlSetVgpuVersion: Result<
+        unsafe extern "C" fn(vgpuVersion: *mut nvmlVgpuVersion_t) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuUtilization: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            lastSeenTimeStamp: ::std::os::raw::c_ulonglong,
+            sampleValType: *mut nvmlValueType_t,
+            vgpuInstanceSamplesCount: *mut ::std::os::raw::c_uint,
+            utilizationSamples: *mut nvmlVgpuInstanceUtilizationSample_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuInstancesUtilizationInfo: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            vgpuUtilInfo: *mut nvmlVgpuInstancesUtilizationInfo_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuProcessUtilization: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            lastSeenTimeStamp: ::std::os::raw::c_ulonglong,
+            vgpuProcessSamplesCount: *mut ::std::os::raw::c_uint,
+            utilizationSamples: *mut nvmlVgpuProcessUtilizationSample_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlDeviceGetVgpuProcessesUtilizationInfo: Result<
+        unsafe extern "C" fn(
+            device: nvmlDevice_t,
+            vgpuProcUtilInfo: *mut nvmlVgpuProcessesUtilizationInfo_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetAccountingMode: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            mode: *mut nvmlEnableState_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetAccountingPids: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            count: *mut ::std::os::raw::c_uint,
+            pids: *mut ::std::os::raw::c_uint,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetAccountingStats: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            pid: ::std::os::raw::c_uint,
+            stats: *mut nvmlAccountingStats_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceClearAccountingPids: Result<
+        unsafe extern "C" fn(vgpuInstance: nvmlVgpuInstance_t) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+    pub nvmlVgpuInstanceGetLicenseInfo_v2: Result<
+        unsafe extern "C" fn(
+            vgpuInstance: nvmlVgpuInstance_t,
+            licenseInfo: *mut nvmlVgpuLicenseInfo_t,
+        ) -> nvmlReturn_t,
+        ::libloading::Error,
+    >,
+}
+impl NvmlLib {
+    pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error>
+    where
+        P: AsRef<::std::ffi::OsStr>,
+    {
+        let library = ::libloading::Library::new(path)?;
+        Self::from_library(library)
+    }
+    pub unsafe fn from_library<L>(library: L) -> Result<Self, ::libloading::Error>
+    where
+        L: Into<::libloading::Library>,
+    {
+        let __library = library.into();
+        let nvmlInit_v2 = __library.get(b"nvmlInit_v2\0").map(|sym| *sym);
+        let nvmlShutdown = __library.get(b"nvmlShutdown\0").map(|sym| *sym);
+        let nvmlErrorString = __library.get(b"nvmlErrorString\0").map(|sym| *sym);
+        let nvmlDeviceGetHandleByIndex_v2 = __library
+            .get(b"nvmlDeviceGetHandleByIndex_v2\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetHandleBySerial = __library
+            .get(b"nvmlDeviceGetHandleBySerial\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetHandleByUUID = __library
+            .get(b"nvmlDeviceGetHandleByUUID\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetHandleByUUIDV = __library
+            .get(b"nvmlDeviceGetHandleByUUIDV\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetHandleByPciBusId_v2 = __library
+            .get(b"nvmlDeviceGetHandleByPciBusId_v2\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetHostVgpuMode = __library
+            .get(b"nvmlDeviceGetHostVgpuMode\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetVgpuHeterogeneousMode = __library
+            .get(b"nvmlDeviceGetVgpuHeterogeneousMode\0")
+            .map(|sym| *sym);
+        let nvmlDeviceSetVgpuHeterogeneousMode = __library
+            .get(b"nvmlDeviceSetVgpuHeterogeneousMode\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetPlacementId = __library
+            .get(b"nvmlVgpuInstanceGetPlacementId\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetVgpuTypeSupportedPlacements = __library
+            .get(b"nvmlDeviceGetVgpuTypeSupportedPlacements\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetVgpuTypeCreatablePlacements = __library
+            .get(b"nvmlDeviceGetVgpuTypeCreatablePlacements\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetGspHeapSize = __library
+            .get(b"nvmlVgpuTypeGetGspHeapSize\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetFbReservation = __library
+            .get(b"nvmlVgpuTypeGetFbReservation\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetRuntimeStateSize = __library
+            .get(b"nvmlVgpuInstanceGetRuntimeStateSize\0")
+            .map(|sym| *sym);
+        let nvmlDeviceSetVgpuCapabilities = __library
+            .get(b"nvmlDeviceSetVgpuCapabilities\0")
+            .map(|sym| *sym);
+        let nvmlGetVgpuDriverCapabilities = __library
+            .get(b"nvmlGetVgpuDriverCapabilities\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetVgpuCapabilities = __library
+            .get(b"nvmlDeviceGetVgpuCapabilities\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetSupportedVgpus = __library
+            .get(b"nvmlDeviceGetSupportedVgpus\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetCreatableVgpus = __library
+            .get(b"nvmlDeviceGetCreatableVgpus\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetClass = __library.get(b"nvmlVgpuTypeGetClass\0").map(|sym| *sym);
+        let nvmlVgpuTypeGetName = __library.get(b"nvmlVgpuTypeGetName\0").map(|sym| *sym);
+        let nvmlVgpuTypeGetGpuInstanceProfileId = __library
+            .get(b"nvmlVgpuTypeGetGpuInstanceProfileId\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetDeviceID = __library.get(b"nvmlVgpuTypeGetDeviceID\0").map(|sym| *sym);
+        let nvmlVgpuTypeGetFramebufferSize = __library
+            .get(b"nvmlVgpuTypeGetFramebufferSize\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetNumDisplayHeads = __library
+            .get(b"nvmlVgpuTypeGetNumDisplayHeads\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetResolution = __library
+            .get(b"nvmlVgpuTypeGetResolution\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetLicense = __library.get(b"nvmlVgpuTypeGetLicense\0").map(|sym| *sym);
+        let nvmlVgpuTypeGetFrameRateLimit = __library
+            .get(b"nvmlVgpuTypeGetFrameRateLimit\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetMaxInstances = __library
+            .get(b"nvmlVgpuTypeGetMaxInstances\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetMaxInstancesPerVm = __library
+            .get(b"nvmlVgpuTypeGetMaxInstancesPerVm\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetBAR1Info = __library.get(b"nvmlVgpuTypeGetBAR1Info\0").map(|sym| *sym);
+        let nvmlDeviceGetActiveVgpus = __library.get(b"nvmlDeviceGetActiveVgpus\0").map(|sym| *sym);
+        let nvmlVgpuInstanceGetVmID = __library.get(b"nvmlVgpuInstanceGetVmID\0").map(|sym| *sym);
+        let nvmlVgpuInstanceGetUUID = __library.get(b"nvmlVgpuInstanceGetUUID\0").map(|sym| *sym);
+        let nvmlVgpuInstanceGetVmDriverVersion = __library
+            .get(b"nvmlVgpuInstanceGetVmDriverVersion\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetFbUsage = __library
+            .get(b"nvmlVgpuInstanceGetFbUsage\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetLicenseStatus = __library
+            .get(b"nvmlVgpuInstanceGetLicenseStatus\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetType = __library.get(b"nvmlVgpuInstanceGetType\0").map(|sym| *sym);
+        let nvmlVgpuInstanceGetFrameRateLimit = __library
+            .get(b"nvmlVgpuInstanceGetFrameRateLimit\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetEccMode = __library
+            .get(b"nvmlVgpuInstanceGetEccMode\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetEncoderCapacity = __library
+            .get(b"nvmlVgpuInstanceGetEncoderCapacity\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceSetEncoderCapacity = __library
+            .get(b"nvmlVgpuInstanceSetEncoderCapacity\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetEncoderStats = __library
+            .get(b"nvmlVgpuInstanceGetEncoderStats\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetEncoderSessions = __library
+            .get(b"nvmlVgpuInstanceGetEncoderSessions\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetFBCStats = __library
+            .get(b"nvmlVgpuInstanceGetFBCStats\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetFBCSessions = __library
+            .get(b"nvmlVgpuInstanceGetFBCSessions\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetGpuInstanceId = __library
+            .get(b"nvmlVgpuInstanceGetGpuInstanceId\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetGpuPciId = __library
+            .get(b"nvmlVgpuInstanceGetGpuPciId\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetCapabilities = __library
+            .get(b"nvmlVgpuTypeGetCapabilities\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetMdevUUID = __library
+            .get(b"nvmlVgpuInstanceGetMdevUUID\0")
+            .map(|sym| *sym);
+        let nvmlGpuInstanceGetCreatableVgpus = __library
+            .get(b"nvmlGpuInstanceGetCreatableVgpus\0")
+            .map(|sym| *sym);
+        let nvmlVgpuTypeGetMaxInstancesPerGpuInstance = __library
+            .get(b"nvmlVgpuTypeGetMaxInstancesPerGpuInstance\0")
+            .map(|sym| *sym);
+        let nvmlGpuInstanceGetActiveVgpus = __library
+            .get(b"nvmlGpuInstanceGetActiveVgpus\0")
+            .map(|sym| *sym);
+        let nvmlGpuInstanceSetVgpuSchedulerState = __library
+            .get(b"nvmlGpuInstanceSetVgpuSchedulerState\0")
+            .map(|sym| *sym);
+        let nvmlGpuInstanceGetVgpuSchedulerState = __library
+            .get(b"nvmlGpuInstanceGetVgpuSchedulerState\0")
+            .map(|sym| *sym);
+        let nvmlGpuInstanceGetVgpuSchedulerLog = __library
+            .get(b"nvmlGpuInstanceGetVgpuSchedulerLog\0")
+            .map(|sym| *sym);
+        let nvmlGpuInstanceGetVgpuTypeCreatablePlacements = __library
+            .get(b"nvmlGpuInstanceGetVgpuTypeCreatablePlacements\0")
+            .map(|sym| *sym);
+        let nvmlGpuInstanceGetVgpuHeterogeneousMode = __library
+            .get(b"nvmlGpuInstanceGetVgpuHeterogeneousMode\0")
+            .map(|sym| *sym);
+        let nvmlGpuInstanceSetVgpuHeterogeneousMode = __library
+            .get(b"nvmlGpuInstanceSetVgpuHeterogeneousMode\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetMetadata = __library
+            .get(b"nvmlVgpuInstanceGetMetadata\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetVgpuMetadata = __library
+            .get(b"nvmlDeviceGetVgpuMetadata\0")
+            .map(|sym| *sym);
+        let nvmlGetVgpuCompatibility = __library.get(b"nvmlGetVgpuCompatibility\0").map(|sym| *sym);
+        let nvmlDeviceGetVgpuSchedulerLog = __library
+            .get(b"nvmlDeviceGetVgpuSchedulerLog\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetVgpuSchedulerState = __library
+            .get(b"nvmlDeviceGetVgpuSchedulerState\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetVgpuSchedulerCapabilities = __library
+            .get(b"nvmlDeviceGetVgpuSchedulerCapabilities\0")
+            .map(|sym| *sym);
+        let nvmlDeviceSetVgpuSchedulerState = __library
+            .get(b"nvmlDeviceSetVgpuSchedulerState\0")
+            .map(|sym| *sym);
+        let nvmlGetVgpuVersion = __library.get(b"nvmlGetVgpuVersion\0").map(|sym| *sym);
+        let nvmlSetVgpuVersion = __library.get(b"nvmlSetVgpuVersion\0").map(|sym| *sym);
+        let nvmlDeviceGetVgpuUtilization = __library
+            .get(b"nvmlDeviceGetVgpuUtilization\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetVgpuInstancesUtilizationInfo = __library
+            .get(b"nvmlDeviceGetVgpuInstancesUtilizationInfo\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetVgpuProcessUtilization = __library
+            .get(b"nvmlDeviceGetVgpuProcessUtilization\0")
+            .map(|sym| *sym);
+        let nvmlDeviceGetVgpuProcessesUtilizationInfo = __library
+            .get(b"nvmlDeviceGetVgpuProcessesUtilizationInfo\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetAccountingMode = __library
+            .get(b"nvmlVgpuInstanceGetAccountingMode\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetAccountingPids = __library
+            .get(b"nvmlVgpuInstanceGetAccountingPids\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetAccountingStats = __library
+            .get(b"nvmlVgpuInstanceGetAccountingStats\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceClearAccountingPids = __library
+            .get(b"nvmlVgpuInstanceClearAccountingPids\0")
+            .map(|sym| *sym);
+        let nvmlVgpuInstanceGetLicenseInfo_v2 = __library
+            .get(b"nvmlVgpuInstanceGetLicenseInfo_v2\0")
+            .map(|sym| *sym);
+        Ok(NvmlLib {
+            __library,
+            nvmlInit_v2,
+            nvmlShutdown,
+            nvmlErrorString,
+            nvmlDeviceGetHandleByIndex_v2,
+            nvmlDeviceGetHandleBySerial,
+            nvmlDeviceGetHandleByUUID,
+            nvmlDeviceGetHandleByUUIDV,
+            nvmlDeviceGetHandleByPciBusId_v2,
+            nvmlDeviceGetHostVgpuMode,
+            nvmlDeviceGetVgpuHeterogeneousMode,
+            nvmlDeviceSetVgpuHeterogeneousMode,
+            nvmlVgpuInstanceGetPlacementId,
+            nvmlDeviceGetVgpuTypeSupportedPlacements,
+            nvmlDeviceGetVgpuTypeCreatablePlacements,
+            nvmlVgpuTypeGetGspHeapSize,
+            nvmlVgpuTypeGetFbReservation,
+            nvmlVgpuInstanceGetRuntimeStateSize,
+            nvmlDeviceSetVgpuCapabilities,
+            nvmlGetVgpuDriverCapabilities,
+            nvmlDeviceGetVgpuCapabilities,
+            nvmlDeviceGetSupportedVgpus,
+            nvmlDeviceGetCreatableVgpus,
+            nvmlVgpuTypeGetClass,
+            nvmlVgpuTypeGetName,
+            nvmlVgpuTypeGetGpuInstanceProfileId,
+            nvmlVgpuTypeGetDeviceID,
+            nvmlVgpuTypeGetFramebufferSize,
+            nvmlVgpuTypeGetNumDisplayHeads,
+            nvmlVgpuTypeGetResolution,
+            nvmlVgpuTypeGetLicense,
+            nvmlVgpuTypeGetFrameRateLimit,
+            nvmlVgpuTypeGetMaxInstances,
+            nvmlVgpuTypeGetMaxInstancesPerVm,
+            nvmlVgpuTypeGetBAR1Info,
+            nvmlDeviceGetActiveVgpus,
+            nvmlVgpuInstanceGetVmID,
+            nvmlVgpuInstanceGetUUID,
+            nvmlVgpuInstanceGetVmDriverVersion,
+            nvmlVgpuInstanceGetFbUsage,
+            nvmlVgpuInstanceGetLicenseStatus,
+            nvmlVgpuInstanceGetType,
+            nvmlVgpuInstanceGetFrameRateLimit,
+            nvmlVgpuInstanceGetEccMode,
+            nvmlVgpuInstanceGetEncoderCapacity,
+            nvmlVgpuInstanceSetEncoderCapacity,
+            nvmlVgpuInstanceGetEncoderStats,
+            nvmlVgpuInstanceGetEncoderSessions,
+            nvmlVgpuInstanceGetFBCStats,
+            nvmlVgpuInstanceGetFBCSessions,
+            nvmlVgpuInstanceGetGpuInstanceId,
+            nvmlVgpuInstanceGetGpuPciId,
+            nvmlVgpuTypeGetCapabilities,
+            nvmlVgpuInstanceGetMdevUUID,
+            nvmlGpuInstanceGetCreatableVgpus,
+            nvmlVgpuTypeGetMaxInstancesPerGpuInstance,
+            nvmlGpuInstanceGetActiveVgpus,
+            nvmlGpuInstanceSetVgpuSchedulerState,
+            nvmlGpuInstanceGetVgpuSchedulerState,
+            nvmlGpuInstanceGetVgpuSchedulerLog,
+            nvmlGpuInstanceGetVgpuTypeCreatablePlacements,
+            nvmlGpuInstanceGetVgpuHeterogeneousMode,
+            nvmlGpuInstanceSetVgpuHeterogeneousMode,
+            nvmlVgpuInstanceGetMetadata,
+            nvmlDeviceGetVgpuMetadata,
+            nvmlGetVgpuCompatibility,
+            nvmlDeviceGetVgpuSchedulerLog,
+            nvmlDeviceGetVgpuSchedulerState,
+            nvmlDeviceGetVgpuSchedulerCapabilities,
+            nvmlDeviceSetVgpuSchedulerState,
+            nvmlGetVgpuVersion,
+            nvmlSetVgpuVersion,
+            nvmlDeviceGetVgpuUtilization,
+            nvmlDeviceGetVgpuInstancesUtilizationInfo,
+            nvmlDeviceGetVgpuProcessUtilization,
+            nvmlDeviceGetVgpuProcessesUtilizationInfo,
+            nvmlVgpuInstanceGetAccountingMode,
+            nvmlVgpuInstanceGetAccountingPids,
+            nvmlVgpuInstanceGetAccountingStats,
+            nvmlVgpuInstanceClearAccountingPids,
+            nvmlVgpuInstanceGetLicenseInfo_v2,
+        })
+    }
+    pub unsafe fn nvmlInit_v2(&self) -> nvmlReturn_t {
+        (self
+            .nvmlInit_v2
+            .as_ref()
+            .expect("Expected function, got error."))()
+    }
+    pub unsafe fn nvmlShutdown(&self) -> nvmlReturn_t {
+        (self
+            .nvmlShutdown
+            .as_ref()
+            .expect("Expected function, got error."))()
+    }
+    pub unsafe fn nvmlErrorString(&self, result: nvmlReturn_t) -> *const ::std::os::raw::c_char {
+        (self
+            .nvmlErrorString
+            .as_ref()
+            .expect("Expected function, got error."))(result)
+    }
+    pub unsafe fn nvmlDeviceGetHandleByIndex_v2(
+        &self,
+        index: ::std::os::raw::c_uint,
+        device: *mut nvmlDevice_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetHandleByIndex_v2
+            .as_ref()
+            .expect("Expected function, got error."))(index, device)
+    }
+    pub unsafe fn nvmlDeviceGetHandleBySerial(
+        &self,
+        serial: *const ::std::os::raw::c_char,
+        device: *mut nvmlDevice_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetHandleBySerial
+            .as_ref()
+            .expect("Expected function, got error."))(serial, device)
+    }
+    pub unsafe fn nvmlDeviceGetHandleByUUID(
+        &self,
+        uuid: *const ::std::os::raw::c_char,
+        device: *mut nvmlDevice_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetHandleByUUID
+            .as_ref()
+            .expect("Expected function, got error."))(uuid, device)
+    }
+    pub unsafe fn nvmlDeviceGetHandleByUUIDV(
+        &self,
+        uuid: *const nvmlUUID_t,
+        device: *mut nvmlDevice_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetHandleByUUIDV
+            .as_ref()
+            .expect("Expected function, got error."))(uuid, device)
+    }
+    pub unsafe fn nvmlDeviceGetHandleByPciBusId_v2(
+        &self,
+        pciBusId: *const ::std::os::raw::c_char,
+        device: *mut nvmlDevice_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetHandleByPciBusId_v2
+            .as_ref()
+            .expect("Expected function, got error."))(pciBusId, device)
+    }
+    pub unsafe fn nvmlDeviceGetHostVgpuMode(
+        &self,
+        device: nvmlDevice_t,
+        pHostVgpuMode: *mut nvmlHostVgpuMode_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetHostVgpuMode
+            .as_ref()
+            .expect("Expected function, got error."))(device, pHostVgpuMode)
+    }
+    pub unsafe fn nvmlDeviceGetVgpuHeterogeneousMode(
+        &self,
+        device: nvmlDevice_t,
+        pHeterogeneousMode: *mut nvmlVgpuHeterogeneousMode_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuHeterogeneousMode
+            .as_ref()
+            .expect("Expected function, got error."))(device, pHeterogeneousMode)
+    }
+    pub unsafe fn nvmlDeviceSetVgpuHeterogeneousMode(
+        &self,
+        device: nvmlDevice_t,
+        pHeterogeneousMode: *const nvmlVgpuHeterogeneousMode_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceSetVgpuHeterogeneousMode
+            .as_ref()
+            .expect("Expected function, got error."))(device, pHeterogeneousMode)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetPlacementId(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        pPlacement: *mut nvmlVgpuPlacementId_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetPlacementId
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, pPlacement)
+    }
+    pub unsafe fn nvmlDeviceGetVgpuTypeSupportedPlacements(
+        &self,
+        device: nvmlDevice_t,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        pPlacementList: *mut nvmlVgpuPlacementList_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuTypeSupportedPlacements
+            .as_ref()
+            .expect("Expected function, got error."))(device, vgpuTypeId, pPlacementList)
+    }
+    pub unsafe fn nvmlDeviceGetVgpuTypeCreatablePlacements(
+        &self,
+        device: nvmlDevice_t,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        pPlacementList: *mut nvmlVgpuPlacementList_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuTypeCreatablePlacements
+            .as_ref()
+            .expect("Expected function, got error."))(device, vgpuTypeId, pPlacementList)
+    }
+    pub unsafe fn nvmlVgpuTypeGetGspHeapSize(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        gspHeapSize: *mut ::std::os::raw::c_ulonglong,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetGspHeapSize
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, gspHeapSize)
+    }
+    pub unsafe fn nvmlVgpuTypeGetFbReservation(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        fbReservation: *mut ::std::os::raw::c_ulonglong,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetFbReservation
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, fbReservation)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetRuntimeStateSize(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        pState: *mut nvmlVgpuRuntimeState_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetRuntimeStateSize
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, pState)
+    }
+    pub unsafe fn nvmlDeviceSetVgpuCapabilities(
+        &self,
+        device: nvmlDevice_t,
+        capability: nvmlDeviceVgpuCapability_t,
+        state: nvmlEnableState_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceSetVgpuCapabilities
+            .as_ref()
+            .expect("Expected function, got error."))(device, capability, state)
+    }
+    pub unsafe fn nvmlGetVgpuDriverCapabilities(
+        &self,
+        capability: nvmlVgpuDriverCapability_t,
+        capResult: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGetVgpuDriverCapabilities
+            .as_ref()
+            .expect("Expected function, got error."))(capability, capResult)
+    }
+    pub unsafe fn nvmlDeviceGetVgpuCapabilities(
+        &self,
+        device: nvmlDevice_t,
+        capability: nvmlDeviceVgpuCapability_t,
+        capResult: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuCapabilities
+            .as_ref()
+            .expect("Expected function, got error."))(device, capability, capResult)
+    }
+    pub unsafe fn nvmlDeviceGetSupportedVgpus(
+        &self,
+        device: nvmlDevice_t,
+        vgpuCount: *mut ::std::os::raw::c_uint,
+        vgpuTypeIds: *mut nvmlVgpuTypeId_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetSupportedVgpus
+            .as_ref()
+            .expect("Expected function, got error."))(device, vgpuCount, vgpuTypeIds)
+    }
+    pub unsafe fn nvmlDeviceGetCreatableVgpus(
+        &self,
+        device: nvmlDevice_t,
+        vgpuCount: *mut ::std::os::raw::c_uint,
+        vgpuTypeIds: *mut nvmlVgpuTypeId_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetCreatableVgpus
+            .as_ref()
+            .expect("Expected function, got error."))(device, vgpuCount, vgpuTypeIds)
+    }
+    pub unsafe fn nvmlVgpuTypeGetClass(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        vgpuTypeClass: *mut ::std::os::raw::c_char,
+        size: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetClass
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, vgpuTypeClass, size)
+    }
+    pub unsafe fn nvmlVgpuTypeGetName(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        vgpuTypeName: *mut ::std::os::raw::c_char,
+        size: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetName
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, vgpuTypeName, size)
+    }
+    pub unsafe fn nvmlVgpuTypeGetGpuInstanceProfileId(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        gpuInstanceProfileId: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetGpuInstanceProfileId
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, gpuInstanceProfileId)
+    }
+    pub unsafe fn nvmlVgpuTypeGetDeviceID(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        deviceID: *mut ::std::os::raw::c_ulonglong,
+        subsystemID: *mut ::std::os::raw::c_ulonglong,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetDeviceID
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, deviceID, subsystemID)
+    }
+    pub unsafe fn nvmlVgpuTypeGetFramebufferSize(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        fbSize: *mut ::std::os::raw::c_ulonglong,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetFramebufferSize
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, fbSize)
+    }
+    pub unsafe fn nvmlVgpuTypeGetNumDisplayHeads(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        numDisplayHeads: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetNumDisplayHeads
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, numDisplayHeads)
+    }
+    pub unsafe fn nvmlVgpuTypeGetResolution(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        displayIndex: ::std::os::raw::c_uint,
+        xdim: *mut ::std::os::raw::c_uint,
+        ydim: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetResolution
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, displayIndex, xdim, ydim)
+    }
+    pub unsafe fn nvmlVgpuTypeGetLicense(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        vgpuTypeLicenseString: *mut ::std::os::raw::c_char,
+        size: ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetLicense
+            .as_ref()
+            .expect("Expected function, got error."))(
+            vgpuTypeId, vgpuTypeLicenseString, size
+        )
+    }
+    pub unsafe fn nvmlVgpuTypeGetFrameRateLimit(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        frameRateLimit: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetFrameRateLimit
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, frameRateLimit)
+    }
+    pub unsafe fn nvmlVgpuTypeGetMaxInstances(
+        &self,
+        device: nvmlDevice_t,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        vgpuInstanceCount: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetMaxInstances
+            .as_ref()
+            .expect("Expected function, got error."))(device, vgpuTypeId, vgpuInstanceCount)
+    }
+    pub unsafe fn nvmlVgpuTypeGetMaxInstancesPerVm(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        vgpuInstanceCountPerVm: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetMaxInstancesPerVm
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, vgpuInstanceCountPerVm)
+    }
+    pub unsafe fn nvmlVgpuTypeGetBAR1Info(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        bar1Info: *mut nvmlVgpuTypeBar1Info_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetBAR1Info
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, bar1Info)
+    }
+    pub unsafe fn nvmlDeviceGetActiveVgpus(
+        &self,
+        device: nvmlDevice_t,
+        vgpuCount: *mut ::std::os::raw::c_uint,
+        vgpuInstances: *mut nvmlVgpuInstance_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetActiveVgpus
+            .as_ref()
+            .expect("Expected function, got error."))(device, vgpuCount, vgpuInstances)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetVmID(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        vmId: *mut ::std::os::raw::c_char,
+        size: ::std::os::raw::c_uint,
+        vmIdType: *mut nvmlVgpuVmIdType_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetVmID
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, vmId, size, vmIdType)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetUUID(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        uuid: *mut ::std::os::raw::c_char,
+        size: ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetUUID
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, uuid, size)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetVmDriverVersion(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        version: *mut ::std::os::raw::c_char,
+        length: ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetVmDriverVersion
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, version, length)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetFbUsage(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        fbUsage: *mut ::std::os::raw::c_ulonglong,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetFbUsage
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, fbUsage)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetLicenseStatus(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        licensed: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetLicenseStatus
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, licensed)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetType(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        vgpuTypeId: *mut nvmlVgpuTypeId_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetType
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, vgpuTypeId)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetFrameRateLimit(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        frameRateLimit: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetFrameRateLimit
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, frameRateLimit)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetEccMode(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        eccMode: *mut nvmlEnableState_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetEccMode
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, eccMode)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetEncoderCapacity(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        encoderCapacity: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetEncoderCapacity
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, encoderCapacity)
+    }
+    pub unsafe fn nvmlVgpuInstanceSetEncoderCapacity(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        encoderCapacity: ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceSetEncoderCapacity
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, encoderCapacity)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetEncoderStats(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        sessionCount: *mut ::std::os::raw::c_uint,
+        averageFps: *mut ::std::os::raw::c_uint,
+        averageLatency: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetEncoderStats
+            .as_ref()
+            .expect("Expected function, got error."))(
+            vgpuInstance,
+            sessionCount,
+            averageFps,
+            averageLatency,
+        )
+    }
+    pub unsafe fn nvmlVgpuInstanceGetEncoderSessions(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        sessionCount: *mut ::std::os::raw::c_uint,
+        sessionInfo: *mut nvmlEncoderSessionInfo_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetEncoderSessions
+            .as_ref()
+            .expect("Expected function, got error."))(
+            vgpuInstance, sessionCount, sessionInfo
+        )
+    }
+    pub unsafe fn nvmlVgpuInstanceGetFBCStats(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        fbcStats: *mut nvmlFBCStats_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetFBCStats
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, fbcStats)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetFBCSessions(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        sessionCount: *mut ::std::os::raw::c_uint,
+        sessionInfo: *mut nvmlFBCSessionInfo_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetFBCSessions
+            .as_ref()
+            .expect("Expected function, got error."))(
+            vgpuInstance, sessionCount, sessionInfo
+        )
+    }
+    pub unsafe fn nvmlVgpuInstanceGetGpuInstanceId(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        gpuInstanceId: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetGpuInstanceId
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, gpuInstanceId)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetGpuPciId(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        vgpuPciId: *mut ::std::os::raw::c_char,
+        length: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetGpuPciId
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, vgpuPciId, length)
+    }
+    pub unsafe fn nvmlVgpuTypeGetCapabilities(
+        &self,
+        vgpuTypeId: nvmlVgpuTypeId_t,
+        capability: nvmlVgpuCapability_t,
+        capResult: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetCapabilities
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuTypeId, capability, capResult)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetMdevUUID(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        mdevUuid: *mut ::std::os::raw::c_char,
+        size: ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetMdevUUID
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, mdevUuid, size)
+    }
+    pub unsafe fn nvmlGpuInstanceGetCreatableVgpus(
+        &self,
+        gpuInstance: nvmlGpuInstance_t,
+        pVgpus: *mut nvmlVgpuTypeIdInfo_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGpuInstanceGetCreatableVgpus
+            .as_ref()
+            .expect("Expected function, got error."))(gpuInstance, pVgpus)
+    }
+    pub unsafe fn nvmlVgpuTypeGetMaxInstancesPerGpuInstance(
+        &self,
+        pMaxInstance: *mut nvmlVgpuTypeMaxInstance_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuTypeGetMaxInstancesPerGpuInstance
+            .as_ref()
+            .expect("Expected function, got error."))(pMaxInstance)
+    }
+    pub unsafe fn nvmlGpuInstanceGetActiveVgpus(
+        &self,
+        gpuInstance: nvmlGpuInstance_t,
+        pVgpuInstanceInfo: *mut nvmlActiveVgpuInstanceInfo_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGpuInstanceGetActiveVgpus
+            .as_ref()
+            .expect("Expected function, got error."))(gpuInstance, pVgpuInstanceInfo)
+    }
+    pub unsafe fn nvmlGpuInstanceSetVgpuSchedulerState(
+        &self,
+        gpuInstance: nvmlGpuInstance_t,
+        pScheduler: *mut nvmlVgpuSchedulerState_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGpuInstanceSetVgpuSchedulerState
+            .as_ref()
+            .expect("Expected function, got error."))(gpuInstance, pScheduler)
+    }
+    pub unsafe fn nvmlGpuInstanceGetVgpuSchedulerState(
+        &self,
+        gpuInstance: nvmlGpuInstance_t,
+        pSchedulerStateInfo: *mut nvmlVgpuSchedulerStateInfo_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGpuInstanceGetVgpuSchedulerState
+            .as_ref()
+            .expect("Expected function, got error."))(gpuInstance, pSchedulerStateInfo)
+    }
+    pub unsafe fn nvmlGpuInstanceGetVgpuSchedulerLog(
+        &self,
+        gpuInstance: nvmlGpuInstance_t,
+        pSchedulerLogInfo: *mut nvmlVgpuSchedulerLogInfo_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGpuInstanceGetVgpuSchedulerLog
+            .as_ref()
+            .expect("Expected function, got error."))(gpuInstance, pSchedulerLogInfo)
+    }
+    pub unsafe fn nvmlGpuInstanceGetVgpuTypeCreatablePlacements(
+        &self,
+        gpuInstance: nvmlGpuInstance_t,
+        pCreatablePlacementInfo: *mut nvmlVgpuCreatablePlacementInfo_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGpuInstanceGetVgpuTypeCreatablePlacements
+            .as_ref()
+            .expect("Expected function, got error."))(gpuInstance, pCreatablePlacementInfo)
+    }
+    pub unsafe fn nvmlGpuInstanceGetVgpuHeterogeneousMode(
+        &self,
+        gpuInstance: nvmlGpuInstance_t,
+        pHeterogeneousMode: *mut nvmlVgpuHeterogeneousMode_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGpuInstanceGetVgpuHeterogeneousMode
+            .as_ref()
+            .expect("Expected function, got error."))(gpuInstance, pHeterogeneousMode)
+    }
+    pub unsafe fn nvmlGpuInstanceSetVgpuHeterogeneousMode(
+        &self,
+        gpuInstance: nvmlGpuInstance_t,
+        pHeterogeneousMode: *const nvmlVgpuHeterogeneousMode_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGpuInstanceSetVgpuHeterogeneousMode
+            .as_ref()
+            .expect("Expected function, got error."))(gpuInstance, pHeterogeneousMode)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetMetadata(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        vgpuMetadata: *mut nvmlVgpuMetadata_t,
+        bufferSize: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetMetadata
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, vgpuMetadata, bufferSize)
+    }
+    pub unsafe fn nvmlDeviceGetVgpuMetadata(
+        &self,
+        device: nvmlDevice_t,
+        pgpuMetadata: *mut nvmlVgpuPgpuMetadata_t,
+        bufferSize: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuMetadata
+            .as_ref()
+            .expect("Expected function, got error."))(device, pgpuMetadata, bufferSize)
+    }
+    pub unsafe fn nvmlGetVgpuCompatibility(
+        &self,
+        vgpuMetadata: *mut nvmlVgpuMetadata_t,
+        pgpuMetadata: *mut nvmlVgpuPgpuMetadata_t,
+        compatibilityInfo: *mut nvmlVgpuPgpuCompatibility_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGetVgpuCompatibility
+            .as_ref()
+            .expect("Expected function, got error."))(
+            vgpuMetadata, pgpuMetadata, compatibilityInfo
+        )
+    }
+    pub unsafe fn nvmlDeviceGetVgpuSchedulerLog(
+        &self,
+        device: nvmlDevice_t,
+        pSchedulerLog: *mut nvmlVgpuSchedulerLog_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuSchedulerLog
+            .as_ref()
+            .expect("Expected function, got error."))(device, pSchedulerLog)
+    }
+    pub unsafe fn nvmlDeviceGetVgpuSchedulerState(
+        &self,
+        device: nvmlDevice_t,
+        pSchedulerState: *mut nvmlVgpuSchedulerGetState_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuSchedulerState
+            .as_ref()
+            .expect("Expected function, got error."))(device, pSchedulerState)
+    }
+    pub unsafe fn nvmlDeviceGetVgpuSchedulerCapabilities(
+        &self,
+        device: nvmlDevice_t,
+        pCapabilities: *mut nvmlVgpuSchedulerCapabilities_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuSchedulerCapabilities
+            .as_ref()
+            .expect("Expected function, got error."))(device, pCapabilities)
+    }
+    pub unsafe fn nvmlDeviceSetVgpuSchedulerState(
+        &self,
+        device: nvmlDevice_t,
+        pSchedulerState: *mut nvmlVgpuSchedulerSetState_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceSetVgpuSchedulerState
+            .as_ref()
+            .expect("Expected function, got error."))(device, pSchedulerState)
+    }
+    pub unsafe fn nvmlGetVgpuVersion(
+        &self,
+        supported: *mut nvmlVgpuVersion_t,
+        current: *mut nvmlVgpuVersion_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlGetVgpuVersion
+            .as_ref()
+            .expect("Expected function, got error."))(supported, current)
+    }
+    pub unsafe fn nvmlSetVgpuVersion(&self, vgpuVersion: *mut nvmlVgpuVersion_t) -> nvmlReturn_t {
+        (self
+            .nvmlSetVgpuVersion
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuVersion)
+    }
+    pub unsafe fn nvmlDeviceGetVgpuUtilization(
+        &self,
+        device: nvmlDevice_t,
+        lastSeenTimeStamp: ::std::os::raw::c_ulonglong,
+        sampleValType: *mut nvmlValueType_t,
+        vgpuInstanceSamplesCount: *mut ::std::os::raw::c_uint,
+        utilizationSamples: *mut nvmlVgpuInstanceUtilizationSample_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuUtilization
+            .as_ref()
+            .expect("Expected function, got error."))(
+            device,
+            lastSeenTimeStamp,
+            sampleValType,
+            vgpuInstanceSamplesCount,
+            utilizationSamples,
+        )
+    }
+    pub unsafe fn nvmlDeviceGetVgpuInstancesUtilizationInfo(
+        &self,
+        device: nvmlDevice_t,
+        vgpuUtilInfo: *mut nvmlVgpuInstancesUtilizationInfo_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuInstancesUtilizationInfo
+            .as_ref()
+            .expect("Expected function, got error."))(device, vgpuUtilInfo)
+    }
+    pub unsafe fn nvmlDeviceGetVgpuProcessUtilization(
+        &self,
+        device: nvmlDevice_t,
+        lastSeenTimeStamp: ::std::os::raw::c_ulonglong,
+        vgpuProcessSamplesCount: *mut ::std::os::raw::c_uint,
+        utilizationSamples: *mut nvmlVgpuProcessUtilizationSample_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuProcessUtilization
+            .as_ref()
+            .expect("Expected function, got error."))(
+            device,
+            lastSeenTimeStamp,
+            vgpuProcessSamplesCount,
+            utilizationSamples,
+        )
+    }
+    pub unsafe fn nvmlDeviceGetVgpuProcessesUtilizationInfo(
+        &self,
+        device: nvmlDevice_t,
+        vgpuProcUtilInfo: *mut nvmlVgpuProcessesUtilizationInfo_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlDeviceGetVgpuProcessesUtilizationInfo
+            .as_ref()
+            .expect("Expected function, got error."))(device, vgpuProcUtilInfo)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetAccountingMode(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        mode: *mut nvmlEnableState_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetAccountingMode
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, mode)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetAccountingPids(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        count: *mut ::std::os::raw::c_uint,
+        pids: *mut ::std::os::raw::c_uint,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetAccountingPids
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, count, pids)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetAccountingStats(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        pid: ::std::os::raw::c_uint,
+        stats: *mut nvmlAccountingStats_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetAccountingStats
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, pid, stats)
+    }
+    pub unsafe fn nvmlVgpuInstanceClearAccountingPids(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceClearAccountingPids
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance)
+    }
+    pub unsafe fn nvmlVgpuInstanceGetLicenseInfo_v2(
+        &self,
+        vgpuInstance: nvmlVgpuInstance_t,
+        licenseInfo: *mut nvmlVgpuLicenseInfo_t,
+    ) -> nvmlReturn_t {
+        (self
+            .nvmlVgpuInstanceGetLicenseInfo_v2
+            .as_ref()
+            .expect("Expected function, got error."))(vgpuInstance, licenseInfo)
+    }
+}
diff --git a/proxmox-ve-vfio/src/nvidia/nvml/mod.rs b/proxmox-ve-vfio/src/nvidia/nvml/mod.rs
new file mode 100644
index 0000000..10ad3c9
--- /dev/null
+++ b/proxmox-ve-vfio/src/nvidia/nvml/mod.rs
@@ -0,0 +1,13 @@
+//! Provides a safe interface to the [NVML], a native library for accessing and
+//! managing the state of NVIDIA GPUs.
+//!
+//! [NVML]: <https://developer.nvidia.com/management-library-nvml>
+
+#[allow(
+    dead_code,
+    non_camel_case_types,
+    non_snake_case,
+    non_upper_case_globals,
+    unused_imports
+)]
+pub mod bindings;
-- 
2.52.0



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [pve-devel] [PATCH proxmox-ve-rs 2/4] vfio: add rust-native interface for accessing NVIDIA vGPU info
  2026-01-20 13:13 [pve-devel] [PATCH proxmox-{ve, perl}-rs/common 0/4] use native libnvidia-ml library for vGPU info Christoph Heiss
  2026-01-20 13:13 ` [pve-devel] [PATCH proxmox-ve-rs 1/4] vfio: add crate for interacting with vfio host devices Christoph Heiss
@ 2026-01-20 13:13 ` Christoph Heiss
  2026-01-20 13:13 ` [pve-devel] [PATCH proxmox-perl-rs 3/4] pve: add bindings for proxmox-ve-vfio Christoph Heiss
  2026-01-20 13:13 ` [pve-devel] [PATCH common 4/4] sysfs: use new PVE::RS::VFIO::Nvidia module to retrieve vGPU info Christoph Heiss
  3 siblings, 0 replies; 6+ messages in thread
From: Christoph Heiss @ 2026-01-20 13:13 UTC (permalink / raw)
  To: pve-devel

Add a "rusty" interface on top of the raw NVML bindings for retrieving
information about creatable vGPU. Will be used to e.g. show a proper
description for each creatable vGPU type.

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
 .../examples/nv_list_creatable_vgpus.rs       |  15 ++
 proxmox-ve-vfio/src/nvidia/mod.rs             | 123 ++++++++++
 proxmox-ve-vfio/src/nvidia/nvml/mod.rs        | 224 ++++++++++++++++++
 3 files changed, 362 insertions(+)
 create mode 100644 proxmox-ve-vfio/examples/nv_list_creatable_vgpus.rs

diff --git a/proxmox-ve-vfio/examples/nv_list_creatable_vgpus.rs b/proxmox-ve-vfio/examples/nv_list_creatable_vgpus.rs
new file mode 100644
index 0000000..b2f276a
--- /dev/null
+++ b/proxmox-ve-vfio/examples/nv_list_creatable_vgpus.rs
@@ -0,0 +1,15 @@
+use std::env;
+
+use proxmox_ve_vfio::nvidia::creatable_vgpu_types_for_dev;
+
+fn main() {
+    let bus_id = env::args()
+        .nth(1)
+        .expect("vGPU bus id expected as first argument, e.g. 00:01.0");
+
+    let types = creatable_vgpu_types_for_dev(&bus_id).expect("failed to retrieve vGPU info");
+
+    for t in types {
+        println!("{}", t.description());
+    }
+}
diff --git a/proxmox-ve-vfio/src/nvidia/mod.rs b/proxmox-ve-vfio/src/nvidia/mod.rs
index 08a414c..bc2ef17 100644
--- a/proxmox-ve-vfio/src/nvidia/mod.rs
+++ b/proxmox-ve-vfio/src/nvidia/mod.rs
@@ -1,3 +1,126 @@
 //! Provides access to the state of NVIDIA (v)GPU devices connected to the system.
 
+use anyhow::Result;
+use serde::Serialize;
+
 mod nvml;
+
+use nvml::bindings::{nvmlDevice_t, nvmlVgpuTypeId_t};
+
+/// A single vGPU type that is either supported and/or currently creatable
+/// for a given GPU.
+#[derive(Serialize)]
+#[serde(rename_all = "kebab-case")]
+pub struct VgpuTypeInfo {
+    /// Unique vGPU type ID.
+    pub id: u32,
+    /// An alphanumeric string that denotes a particular vGPU, e.g. GRID M60-2Q.
+    pub name: String,
+    /// Class of the vGPU, e.g. Quadro.
+    pub class_name: String,
+    /// Maximum number of vGPU instances creatable of this vGPU type.
+    pub max_instances: u32,
+    /// Maximum number of vGPU instances supported per VM for this vGPU type.
+    pub max_instances_per_vm: u32,
+    /// vGPU framebuffer size in bytes.
+    pub framebuffer_size: u64,
+    /// Number of supported display heads by this vGPU type.
+    pub num_heads: u32,
+    /// Maximum resolution of a single head available across all display heads
+    /// supported by this vGPU type.
+    pub max_resolution: (u32, u32),
+    /// License types and versions required to run this specified vGPU type,
+    /// each in the form "\<license name\>,\<version\>", for example
+    /// "GRID-Virtual-PC,2.0".
+    /// A vGPU type might also be runnable with more than one type of license,
+    /// in which cases each license is separated by a semicolon.
+    pub license: String,
+    /// Static frame limit for this vGPU, if the frame limiter is enabled for
+    /// this vGPU type.
+    pub fps_limit: Option<u32>,
+}
+
+impl VgpuTypeInfo {
+    fn get_with(nvml: &nvml::Nvml, dev: nvmlDevice_t, type_id: nvmlVgpuTypeId_t) -> Result<Self> {
+        let num_heads = nvml.vgpu_type_num_display_heads(type_id)?;
+
+        // Take the best resolution among all available display heads
+        let max_resolution = (0..num_heads)
+            .filter_map(|i| nvml.vgpu_type_max_resolution(type_id, i).ok())
+            .max()
+            .unwrap_or((0, 0));
+
+        Ok(VgpuTypeInfo {
+            id: type_id,
+            name: nvml.vgpu_type_name(type_id)?,
+            class_name: nvml.vgpu_type_class_name(type_id)?,
+            max_instances: nvml.vgpu_type_max_instances(dev, type_id)?,
+            max_instances_per_vm: nvml.vgpu_type_max_instances_per_vm(type_id)?,
+            framebuffer_size: nvml.vgpu_type_framebuffer_size(type_id)?,
+            num_heads,
+            max_resolution,
+            license: nvml.vgpu_type_license(type_id)?,
+            fps_limit: nvml.vgpu_type_frame_rate_limit(type_id)?,
+        })
+    }
+
+    /// Formats the descriptive fields of the vGPU type information as a property string.
+    pub fn description(&self) -> String {
+        let VgpuTypeInfo {
+            class_name,
+            max_instances,
+            max_instances_per_vm,
+            framebuffer_size,
+            num_heads,
+            max_resolution,
+            license,
+            ..
+        } = self;
+
+        let framebuffer_size = framebuffer_size / 1024 / 1024;
+        let (max_res_x, max_res_y) = max_resolution;
+
+        format!(
+            "class={class_name}\
+            ,max-instances={max_instances}\
+            ,max-instances-per-vm={max_instances_per_vm}\
+            ,framebuffer-size={framebuffer_size}MiB\
+            ,num-heads={num_heads}\
+            ,max-resolution={max_res_x}x{max_res_y}\
+            ,license={license}"
+        )
+    }
+}
+
+/// Given a concrete GPU device, enumerates all *creatable* vGPU types for this
+/// device.
+fn enumerate_creatable_vgpu_types_by_dev(
+    nvml: &nvml::Nvml,
+    dev: nvmlDevice_t,
+) -> Result<Vec<VgpuTypeInfo>> {
+    let mut vgpu_info = vec![];
+    let type_ids = nvml.device_get_creatable_vgpus(dev)?;
+
+    for type_id in type_ids {
+        vgpu_info.push(VgpuTypeInfo::get_with(nvml, dev, type_id)?);
+    }
+
+    Ok(vgpu_info)
+}
+
+/// Retrieves a list of *creatable* vGPU types for the specified GPU by bus id.
+///
+/// The `bus_id` must be of format "\<domain\>:\<bus\>:\<device\>.\<function\>", e.g.
+/// "0000:01:01.0".
+/// \<domain\> is optional and can be left out if there is only one.
+///
+/// # See also
+///
+/// [`nvmlDeviceGetHandleByPciBusId_v2()`]: <https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1gea7484bb9eac412c28e8a73842254c05>
+/// [`struct nvmlPciInto_t`]: <https://docs.nvidia.com/deploy/nvml-api/structnvmlPciInfo__t.html#structnvmlPciInfo__t_1a4d54ad9b596d7cab96ecc34613adbe4>
+pub fn creatable_vgpu_types_for_dev(bus_id: &str) -> Result<Vec<VgpuTypeInfo>> {
+    let nvml = nvml::Nvml::new()?;
+    let handle = nvml.device_handle_by_bus_id(bus_id)?;
+
+    enumerate_creatable_vgpu_types_by_dev(&nvml, handle)
+}
diff --git a/proxmox-ve-vfio/src/nvidia/nvml/mod.rs b/proxmox-ve-vfio/src/nvidia/nvml/mod.rs
index 10ad3c9..1259095 100644
--- a/proxmox-ve-vfio/src/nvidia/nvml/mod.rs
+++ b/proxmox-ve-vfio/src/nvidia/nvml/mod.rs
@@ -3,6 +3,13 @@
 //!
 //! [NVML]: <https://developer.nvidia.com/management-library-nvml>
 
+use anyhow::{bail, Result};
+use std::{
+    borrow::Cow,
+    ffi::{c_uint, c_ulonglong, CStr},
+    ptr,
+};
+
 #[allow(
     dead_code,
     non_camel_case_types,
@@ -11,3 +18,220 @@
     unused_imports
 )]
 pub mod bindings;
+
+use bindings::{
+    nvmlDevice_t, nvmlReturn_enum_NVML_ERROR_INSUFFICIENT_SIZE,
+    nvmlReturn_enum_NVML_ERROR_NOT_SUPPORTED, nvmlReturn_enum_NVML_SUCCESS, nvmlReturn_t,
+    nvmlVgpuTypeId_t, NvmlLib, NVML_DEVICE_NAME_BUFFER_SIZE, NVML_GRID_LICENSE_BUFFER_SIZE,
+};
+
+/// SONAME/filename of the native NVML, pin it to SOVERSION 1 explicitly to be sure.
+const NVML_LIB_NAME: &str = "libnvidia-ml.so.1";
+
+pub struct Nvml(NvmlLib);
+
+impl Nvml {
+    pub fn new() -> Result<Self> {
+        let lib = unsafe {
+            let lib = Self(NvmlLib::new(NVML_LIB_NAME)?);
+            lib.to_err(lib.0.nvmlInit_v2())?;
+            lib
+        };
+
+        Ok(lib)
+    }
+
+    pub fn device_handle_by_bus_id(&self, bus_id: &str) -> Result<nvmlDevice_t> {
+        let mut handle: nvmlDevice_t = ptr::null_mut();
+        unsafe {
+            self.to_err(
+                self.0
+                    .nvmlDeviceGetHandleByPciBusId_v2(bus_id.as_ptr() as *const i8, &mut handle),
+            )?;
+        }
+
+        Ok(handle)
+    }
+
+    /// Retrieves a list of vGPU types supported by the given device.
+    ///
+    /// # See also
+    ///
+    /// <https://docs.nvidia.com/deploy/nvml-api/group__nvmlVgpu.html#group__nvmlVgpu>
+    pub fn device_get_creatable_vgpus(&self, dev: nvmlDevice_t) -> Result<Vec<nvmlVgpuTypeId_t>> {
+        let mut count: c_uint = 0;
+        let mut ids = vec![];
+
+        unsafe {
+            // First retrieve the number of supported vGPUs by passing count == 0,
+            // which will set `count` to the actual number.
+            let result = self
+                .0
+                .nvmlDeviceGetCreatableVgpus(dev, &mut count, ids.as_mut_ptr());
+
+            #[allow(non_upper_case_globals)]
+            if !matches!(
+                result,
+                nvmlReturn_enum_NVML_SUCCESS | nvmlReturn_enum_NVML_ERROR_INSUFFICIENT_SIZE
+            ) {
+                self.to_err(result)?;
+            }
+
+            ids.resize(count as usize, 0);
+            self.to_err(
+                self.0
+                    .nvmlDeviceGetCreatableVgpus(dev, &mut count, ids.as_mut_ptr()),
+            )?;
+        }
+
+        Ok(ids)
+    }
+
+    pub fn vgpu_type_class_name(&self, type_id: nvmlVgpuTypeId_t) -> Result<String> {
+        let mut buffer: Vec<u8> = vec![0; NVML_DEVICE_NAME_BUFFER_SIZE as usize];
+        let mut buffer_size = buffer.len() as u32;
+
+        unsafe {
+            self.to_err(self.0.nvmlVgpuTypeGetClass(
+                type_id,
+                buffer.as_mut_ptr() as *mut i8,
+                &mut buffer_size,
+            ))?;
+        }
+
+        slice_to_string(&buffer)
+    }
+
+    pub fn vgpu_type_license(&self, type_id: nvmlVgpuTypeId_t) -> Result<String> {
+        let mut buffer: Vec<u8> = vec![0; NVML_GRID_LICENSE_BUFFER_SIZE as usize];
+
+        unsafe {
+            self.to_err(self.0.nvmlVgpuTypeGetLicense(
+                type_id,
+                buffer.as_mut_ptr() as *mut i8,
+                buffer.len() as u32,
+            ))?;
+        }
+
+        slice_to_string(&buffer)
+    }
+
+    pub fn vgpu_type_name(&self, type_id: nvmlVgpuTypeId_t) -> Result<String> {
+        let mut buffer: Vec<u8> = vec![0; NVML_DEVICE_NAME_BUFFER_SIZE as usize];
+        let mut buffer_size = buffer.len() as u32;
+
+        unsafe {
+            self.to_err(self.0.nvmlVgpuTypeGetName(
+                type_id,
+                buffer.as_mut_ptr() as *mut i8,
+                &mut buffer_size,
+            ))?;
+        }
+
+        slice_to_string(&buffer)
+    }
+
+    pub fn vgpu_type_max_instances(
+        &self,
+        dev: nvmlDevice_t,
+        type_id: nvmlVgpuTypeId_t,
+    ) -> Result<u32> {
+        let mut count: c_uint = 0;
+        unsafe {
+            self.to_err(self.0.nvmlVgpuTypeGetMaxInstances(dev, type_id, &mut count))?;
+        }
+
+        Ok(count)
+    }
+
+    pub fn vgpu_type_max_instances_per_vm(&self, type_id: nvmlVgpuTypeId_t) -> Result<u32> {
+        let mut count: c_uint = 0;
+        unsafe {
+            self.to_err(self.0.nvmlVgpuTypeGetMaxInstancesPerVm(type_id, &mut count))?;
+        }
+
+        Ok(count)
+    }
+
+    pub fn vgpu_type_framebuffer_size(&self, type_id: nvmlVgpuTypeId_t) -> Result<u64> {
+        let mut size: c_ulonglong = 0;
+        unsafe {
+            self.to_err(self.0.nvmlVgpuTypeGetFramebufferSize(type_id, &mut size))?;
+        }
+
+        Ok(size)
+    }
+
+    pub fn vgpu_type_num_display_heads(&self, type_id: nvmlVgpuTypeId_t) -> Result<u32> {
+        let mut num: c_uint = 0;
+        unsafe {
+            self.to_err(self.0.nvmlVgpuTypeGetNumDisplayHeads(type_id, &mut num))?;
+        }
+
+        Ok(num)
+    }
+
+    pub fn vgpu_type_max_resolution(
+        &self,
+        type_id: nvmlVgpuTypeId_t,
+        head: u32,
+    ) -> Result<(u32, u32)> {
+        let (mut x, mut y): (c_uint, c_uint) = (0, 0);
+        unsafe {
+            self.to_err(
+                self.0
+                    .nvmlVgpuTypeGetResolution(type_id, head, &mut x, &mut y),
+            )?;
+        }
+
+        Ok((x, y))
+    }
+
+    pub fn vgpu_type_frame_rate_limit(&self, type_id: nvmlVgpuTypeId_t) -> Result<Option<u32>> {
+        let mut limit: c_uint = 0;
+        let result = unsafe { self.0.nvmlVgpuTypeGetFrameRateLimit(type_id, &mut limit) };
+
+        if !Self::err_is_unsupported(result) {
+            Ok(None)
+        } else {
+            self.to_err(result)?;
+            Ok(Some(limit))
+        }
+    }
+
+    fn to_err(&self, result: nvmlReturn_t) -> Result<()> {
+        if result == nvmlReturn_enum_NVML_SUCCESS {
+            Ok(())
+        } else {
+            bail!("{}", self.error_str(result))
+        }
+    }
+
+    fn err_is_unsupported(result: nvmlReturn_t) -> bool {
+        result == nvmlReturn_enum_NVML_ERROR_NOT_SUPPORTED
+    }
+
+    fn error_str(&self, err_code: nvmlReturn_t) -> Cow<'_, str> {
+        let cstr = unsafe {
+            let raw = self.0.nvmlErrorString(err_code);
+            CStr::from_ptr(raw)
+        };
+
+        cstr.to_string_lossy()
+    }
+}
+
+impl Drop for Nvml {
+    fn drop(&mut self) {
+        if let Ok(sym) = self.0.nvmlShutdown.as_ref() {
+            // Although nvmlShutdown() provides a return code (or error) indicating
+            // whether the operation was successful, at this point there isn't
+            // really anything we can do if it throws an error.
+            unsafe { sym() };
+        }
+    }
+}
+
+fn slice_to_string(s: &[u8]) -> Result<String> {
+    Ok(CStr::from_bytes_until_nul(s)?.to_str()?.into())
+}
-- 
2.52.0



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [pve-devel] [PATCH proxmox-perl-rs 3/4] pve: add bindings for proxmox-ve-vfio
  2026-01-20 13:13 [pve-devel] [PATCH proxmox-{ve, perl}-rs/common 0/4] use native libnvidia-ml library for vGPU info Christoph Heiss
  2026-01-20 13:13 ` [pve-devel] [PATCH proxmox-ve-rs 1/4] vfio: add crate for interacting with vfio host devices Christoph Heiss
  2026-01-20 13:13 ` [pve-devel] [PATCH proxmox-ve-rs 2/4] vfio: add rust-native interface for accessing NVIDIA vGPU info Christoph Heiss
@ 2026-01-20 13:13 ` Christoph Heiss
  2026-01-20 13:13 ` [pve-devel] [PATCH common 4/4] sysfs: use new PVE::RS::VFIO::Nvidia module to retrieve vGPU info Christoph Heiss
  3 siblings, 0 replies; 6+ messages in thread
From: Christoph Heiss @ 2026-01-20 13:13 UTC (permalink / raw)
  To: pve-devel

Adds some basic perl binding for the proxmox-ve-vfio, in particular to
retrieve information about creatable vGPU typos for Nvidia host devices.

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
 pve-rs/Cargo.toml                          |  1 +
 pve-rs/Makefile                            |  3 +-
 pve-rs/debian/control                      |  1 +
 pve-rs/examples/nv-list-creatable-vgpus.pl | 20 ++++++++++++
 pve-rs/src/lib.rs                          |  1 +
 pve-rs/src/vfio/mod.rs                     |  6 ++++
 pve-rs/src/vfio/nvidia.rs                  | 38 ++++++++++++++++++++++
 7 files changed, 69 insertions(+), 1 deletion(-)
 create mode 100755 pve-rs/examples/nv-list-creatable-vgpus.pl
 create mode 100644 pve-rs/src/vfio/mod.rs
 create mode 100644 pve-rs/src/vfio/nvidia.rs

diff --git a/pve-rs/Cargo.toml b/pve-rs/Cargo.toml
index 527fcae..4e88942 100644
--- a/pve-rs/Cargo.toml
+++ b/pve-rs/Cargo.toml
@@ -49,6 +49,7 @@ proxmox-sys = "1"
 proxmox-tfa = { version = "6.0.3", features = ["api"] }
 proxmox-time = "2"
 proxmox-ve-config = { version = "0.4.5", features = [ "frr" ] }
+proxmox-ve-vfio = { version = "0.1.0" }
 
 # [patch.crates-io]
 # pbs-api-types = { path = "../../proxmox/pbs-api-types" }
diff --git a/pve-rs/Makefile b/pve-rs/Makefile
index aa7181e..45ee12a 100644
--- a/pve-rs/Makefile
+++ b/pve-rs/Makefile
@@ -31,7 +31,8 @@ PERLMOD_PACKAGES := \
 	  PVE::RS::OpenId \
 	  PVE::RS::ResourceScheduling::Static \
 	  PVE::RS::SDN::Fabrics \
-	  PVE::RS::TFA
+	  PVE::RS::TFA \
+	  PVE::RS::VFIO::Nvidia
 
 PERLMOD_PACKAGE_FILES := $(addsuffix .pm,$(subst ::,/,$(PERLMOD_PACKAGES)))
 
diff --git a/pve-rs/debian/control b/pve-rs/debian/control
index 2743712..ec815f2 100644
--- a/pve-rs/debian/control
+++ b/pve-rs/debian/control
@@ -40,6 +40,7 @@ Build-Depends: cargo:native <!nocheck>,
                librust-proxmox-time-2+default-dev,
                librust-proxmox-ve-config-0.4+default-dev (>= 0.4.5-~~),
                librust-proxmox-ve-config-0.4+frr-dev (>= 0.4.5-~~),
+               librust-proxmox-ve-vfio-dev,
                librust-serde-1+default-dev,
                librust-serde-bytes-0.11+default-dev,
                librust-serde-json-1+default-dev,
diff --git a/pve-rs/examples/nv-list-creatable-vgpus.pl b/pve-rs/examples/nv-list-creatable-vgpus.pl
new file mode 100755
index 0000000..2814860
--- /dev/null
+++ b/pve-rs/examples/nv-list-creatable-vgpus.pl
@@ -0,0 +1,20 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Data::Dumper;
+
+use PVE::RS::VFIO::Nvidia;
+
+my $bus_id = shift;
+
+die "vGPU bus id expected as first argument, e.g. 00:01.0\n"
+    if !defined($bus_id);
+
+my $creatable =
+    PVE::RS::VFIO::Nvidia::creatable_vgpu_types_for_dev($bus_id);
+
+foreach my $vgpu (@$creatable) {
+    print Dumper(\$vgpu);
+}
diff --git a/pve-rs/src/lib.rs b/pve-rs/src/lib.rs
index b32b061..2e337da 100644
--- a/pve-rs/src/lib.rs
+++ b/pve-rs/src/lib.rs
@@ -14,6 +14,7 @@ use proxmox_notify::{Config, Notification, Severity};
 mod common;
 
 mod sdn;
+mod vfio;
 
 pub mod bindings;
 
diff --git a/pve-rs/src/vfio/mod.rs b/pve-rs/src/vfio/mod.rs
new file mode 100644
index 0000000..4c40a8d
--- /dev/null
+++ b/pve-rs/src/vfio/mod.rs
@@ -0,0 +1,6 @@
+//! Exposes an interface for accessing and handling VFIO host devices such as NVIDIA vGPU devices,
+//! to e.g. extract information about them for preparing passthrough.
+
+#![deny(missing_docs)]
+
+pub mod nvidia;
diff --git a/pve-rs/src/vfio/nvidia.rs b/pve-rs/src/vfio/nvidia.rs
new file mode 100644
index 0000000..5dc5730
--- /dev/null
+++ b/pve-rs/src/vfio/nvidia.rs
@@ -0,0 +1,38 @@
+//! Provides access to the state of NVIDIA (v)GPU devices connected to the system.
+
+#[perlmod::package(name = "PVE::RS::VFIO::Nvidia", lib = "pve_rs")]
+mod export {
+    use anyhow::{Result, anyhow};
+    use perlmod::Value;
+    use proxmox_ve_vfio::nvidia;
+
+    /// Retrieves a list of *creatable* vGPU types for the specified GPU by bus id.
+    ///
+    /// The [`bus_id`] is of format "\<domain\>:\<bus\>:\<device\>.\<function\>",
+    /// e.g. "0000:01:01.0".
+    ///
+    /// # See also
+    ///
+    /// [`nvidia::creatable_vgpu_types_for_dev`]
+    /// [`nvmlDeviceGetHandleByPciBusId_v2`]: <https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1gea7484bb9eac412c28e8a73842254c05>
+    /// [`struct nvmlPciInto_t`]: <https://docs.nvidia.com/deploy/nvml-api/structnvmlPciInfo__t.html#structnvmlPciInfo__t_1a4d54ad9b596d7cab96ecc34613adbe4>
+    #[export]
+    fn creatable_vgpu_types_for_dev(bus_id: &str) -> Result<Vec<Value>> {
+        let vgpu_types = nvidia::creatable_vgpu_types_for_dev(bus_id)?;
+
+        let mut result = Vec::with_capacity(vgpu_types.len());
+        for vgpu in vgpu_types {
+            let mut value: Value = perlmod::to_value(&vgpu)?
+                .dereference()
+                .ok_or_else(|| anyhow!("expected reference"))?;
+
+            if let Some(hash) = value.as_hash_mut() {
+                hash.insert("description", Value::new_string(&vgpu.description()));
+            }
+
+            result.push(Value::new_ref(&value));
+        }
+
+        Ok(result)
+    }
+}
-- 
2.52.0



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [pve-devel] [PATCH common 4/4] sysfs: use new PVE::RS::VFIO::Nvidia module to retrieve vGPU info
  2026-01-20 13:13 [pve-devel] [PATCH proxmox-{ve, perl}-rs/common 0/4] use native libnvidia-ml library for vGPU info Christoph Heiss
                   ` (2 preceding siblings ...)
  2026-01-20 13:13 ` [pve-devel] [PATCH proxmox-perl-rs 3/4] pve: add bindings for proxmox-ve-vfio Christoph Heiss
@ 2026-01-20 13:13 ` Christoph Heiss
  2026-01-20 15:00   ` Thomas Lamprecht
  3 siblings, 1 reply; 6+ messages in thread
From: Christoph Heiss @ 2026-01-20 13:13 UTC (permalink / raw)
  To: pve-devel

pci_dev_physfn_id() is used to obtain the parent device of a virtual
function, i.e. the physical function.

Needed for retrieving information about Nvidia vGPU devices via
proxmox-ve-vfio, as libnvidia-ml functions only work with physical
functions.

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
 src/PVE/SysFSTools.pm | 45 ++++++++++++++++++++++++++++++-------------
 1 file changed, 32 insertions(+), 13 deletions(-)

diff --git a/src/PVE/SysFSTools.pm b/src/PVE/SysFSTools.pm
index a00fbcb..89e57b9 100644
--- a/src/PVE/SysFSTools.pm
+++ b/src/PVE/SysFSTools.pm
@@ -4,8 +4,10 @@ use strict;
 use warnings;
 
 use IO::File;
+use File::Basename;
 
 use PVE::Tools qw(file_read_firstline dir_glob_foreach);
+use PVE::RS::VFIO::Nvidia;
 
 my $pcisysfs = "/sys/bus/pci";
 my $domainregex = "[a-f0-9]{4,}";
@@ -157,6 +159,7 @@ sub lspci {
 #         type => 'FooType_1',
 #         description => "a longer description with custom format\nand newlines",
 #         available => 5,
+#         name => "human-readable name of mdev"
 #     },
 #     ...
 # ]
@@ -170,7 +173,7 @@ sub get_mdev_types {
 
     my $dev_path = "$pcisysfs/devices/$id";
     my $mdev_path = "$dev_path/mdev_supported_types";
-    my $nvidia_path = "$dev_path/nvidia/creatable_vgpu_types";
+    my $nvidia_path = "$dev_path/nvidia";
     if (-d $mdev_path) {
         dir_glob_foreach(
             $mdev_path,
@@ -195,20 +198,20 @@ sub get_mdev_types {
                 push @$types, $entry;
             },
         );
-    } elsif (-f $nvidia_path) {
-        my $creatable = PVE::Tools::file_get_contents($nvidia_path);
-        for my $line (split("\n", $creatable)) {
-            next if $line =~ m/^ID/; # header
-            next if $line !~ m/^(.*?)\s*:\s*(.*)$/;
-            my $id = $1;
-            my $name = $2;
+    } elsif (-d $nvidia_path) {
+        $id = pci_dev_physfn_id($id);
+        my $nvtypes = eval { PVE::RS::VFIO::Nvidia::creatable_vgpu_types_for_dev($id); };
 
-            push $types->@*, {
-                type => "nvidia-$id", # backwards compatibility
-                description => "", # TODO, read from xml/nvidia-smi ?
+        if (my $err = $@) {
+            die "failed to get creatable Nvidia vGPU types for $id: $err\n";
+        } else {
+            my @mapped = map { {
+                type => "nvidia-$_->{id}", # backwards compatibility
                 available => 1,
-                name => $name,
-            };
+                description => $_->{description},
+                name => $_->{name},
+            } } @$nvtypes;
+            $types = \@mapped;
         }
     }
 
@@ -409,6 +412,22 @@ sub pci_create_mdev_device {
     return undef;
 }
 
+# Returns the PCI bus id of the physical function (IOW, parent device) of the
+# given device. If the device does not have a parent physical function, returns
+# the given ID unchanged.
+sub pci_dev_physfn_id {
+    my ($id) = @_;
+
+    $id = normalize_pci_id($id);
+    my $devpath = "$pcisysfs/devices/$id";
+
+    if (-d "$devpath/physfn") {
+        return basename(readlink("$devpath/physfn"));
+    } else {
+        return $id;
+    }
+}
+
 # encode the hostpci index and vmid into the uuid
 sub generate_mdev_uuid {
     my ($vmid, $index) = @_;
-- 
2.52.0



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [pve-devel] [PATCH common 4/4] sysfs: use new PVE::RS::VFIO::Nvidia module to retrieve vGPU info
  2026-01-20 13:13 ` [pve-devel] [PATCH common 4/4] sysfs: use new PVE::RS::VFIO::Nvidia module to retrieve vGPU info Christoph Heiss
@ 2026-01-20 15:00   ` Thomas Lamprecht
  0 siblings, 0 replies; 6+ messages in thread
From: Thomas Lamprecht @ 2026-01-20 15:00 UTC (permalink / raw)
  To: Proxmox VE development discussion, Christoph Heiss

Am 20.01.26 um 14:12 schrieb Christoph Heiss:
> pci_dev_physfn_id() is used to obtain the parent device of a virtual
> function, i.e. the physical function.
> 
> Needed for retrieving information about Nvidia vGPU devices via
> proxmox-ve-vfio, as libnvidia-ml functions only work with physical
> functions.
> 
> Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
> ---
>  src/PVE/SysFSTools.pm | 45 ++++++++++++++++++++++++++++++-------------
>  1 file changed, 32 insertions(+), 13 deletions(-)
> 
> diff --git a/src/PVE/SysFSTools.pm b/src/PVE/SysFSTools.pm
> index a00fbcb..89e57b9 100644
> --- a/src/PVE/SysFSTools.pm
> +++ b/src/PVE/SysFSTools.pm
> @@ -4,8 +4,10 @@ use strict;
>  use warnings;
>  
>  use IO::File;
> +use File::Basename;
>  
>  use PVE::Tools qw(file_read_firstline dir_glob_foreach);
> +use PVE::RS::VFIO::Nvidia;

we do not depend on libpve-rs-perl in libpve-common-perl, and if easily possible
I'd strongly favor keeping it that way, bootstrapping and handling bigger package
bumps with newer versioned dependencies or break/depends bumps is already quite
a bit of work as is, such stuff does not make it easier, especially if adding
a new dependencies is not recorded in d/control's packaging definition.

Can this move to some non-leaf package instead? Where are the users of this, only
qemu-server or other too (pve-manager?)?


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-01-20 15:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-20 13:13 [pve-devel] [PATCH proxmox-{ve, perl}-rs/common 0/4] use native libnvidia-ml library for vGPU info Christoph Heiss
2026-01-20 13:13 ` [pve-devel] [PATCH proxmox-ve-rs 1/4] vfio: add crate for interacting with vfio host devices Christoph Heiss
2026-01-20 13:13 ` [pve-devel] [PATCH proxmox-ve-rs 2/4] vfio: add rust-native interface for accessing NVIDIA vGPU info Christoph Heiss
2026-01-20 13:13 ` [pve-devel] [PATCH proxmox-perl-rs 3/4] pve: add bindings for proxmox-ve-vfio Christoph Heiss
2026-01-20 13:13 ` [pve-devel] [PATCH common 4/4] sysfs: use new PVE::RS::VFIO::Nvidia module to retrieve vGPU info Christoph Heiss
2026-01-20 15:00   ` Thomas Lamprecht

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal