Skip to content

vgpu apis - #130

Open
FreeMasen wants to merge 4 commits into
rust-nvml:mainfrom
FreeMasen:feat/some-vgpu-apis
Open

vgpu apis#130
FreeMasen wants to merge 4 commits into
rust-nvml:mainfrom
FreeMasen:feat/some-vgpu-apis

Conversation

@FreeMasen

Copy link
Copy Markdown
Contributor

This PR is an attempt to fully cover the vGPU APIs defined by nvml. To achieve this I've followed the patterns defined for Device and VgpuType to cover all functions in the unwrapped_functions.txt file that are named nvmlVgpu*

The one exception here was nvmlVgpuInstanceGetLicenseStatus which is deprecated and not documented at this time, if you'd like me to dig through older versions of the docs, I can find the documentation for how that API works.

Please let me know if I've misunderstood any of the patterns I've tried to emulate and/or the API documentation, I would be happy to follow up with additional changes as needed.

Note: this is currently marked as a draft because I based these changes on #129 and will rebase once that merges or is declined

@FreeMasen
FreeMasen force-pushed the feat/some-vgpu-apis branch 4 times, most recently from 2b5367f to f3f0229 Compare March 5, 2026 21:03
@FreeMasen
FreeMasen force-pushed the feat/some-vgpu-apis branch from f3f0229 to 970027b Compare March 5, 2026 21:15

@FreeMasen FreeMasen left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is ready for an initial review to make sure I am not doing anything that goes against the goals of this project. I need to dig a little deeper into how testing works for this project to add additional test for these additions.

I am going to leave the Draft status until I can get through tests, any feedback would be welcome!

Comment thread nvml-wrapper/src/enum_wrappers/vgpu.rs
Comment thread nvml-wrapper/src/enum_wrappers/vgpu.rs
Comment thread nvml-wrapper/src/enum_wrappers/vgpu.rs
pub hour: u8,
pub min: u8,
pub sec: u8,
pub status: u8,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find any documentation about why are expected values here and left the type effectively unchanged. Let me know if there is something I missed and I can add another enum to capture the status.

Comment thread nvml-wrapper/src/struct_wrappers/vgpu.rs
Comment thread nvml-wrapper/src/device.rs
impl TryFrom<nvmlVgpuMetadata_t> for VgpuMetadata {
type Error = NvmlError;
fn try_from(value: nvmlVgpuMetadata_t) -> Result<Self, Self::Error> {
let convert_c_str = |c_str: &[c_char]| {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is a bit odd, I wanted to avoid using any unsafe and so this will manually copy the string byte by byte which may not be the most efficient. Let me know if you'd prefer a different method for this or even if lossy conversion is acceptable here

@swlynch99

Copy link
Copy Markdown
Contributor

I'm happy to review this once it is ready. Once you're happy with it lmk.

@FreeMasen
FreeMasen force-pushed the feat/some-vgpu-apis branch from afce533 to c6b1acb Compare March 11, 2026 01:10
Comment thread nvml-wrapper/src/vgpu.rs
let mut count = 0;
unsafe {
nvml_try_count(sym(self.instance, std::ptr::null_mut(), &mut count))?;
metadata = vec![std::mem::zeroed(); count as usize];

@FreeMasen FreeMasen Mar 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about this one, I tried running this function on a machine with an a16 and count was a number that was much larger than the expected buffer size (468) but not a factor of std::mem::size_of::<nvmlVgpuMetadata_t>(); which is 212 according to rust analyzer.

@FreeMasen
FreeMasen marked this pull request as ready for review March 11, 2026 01:17
@FreeMasen

Copy link
Copy Markdown
Contributor Author

I believe this is ready for review. I have tried to comment on any of the places where I wasn't quite sure about how something should be implemented.

@brayniac

Copy link
Copy Markdown
Contributor

Thanks for the extensive work here — this is a high-quality contribution and I'd like to land it. I checked out the branch, merged current main (clean merge, and with #129 long since landed the draft caveat is resolved), and verified it compiles on macOS and Linux targets, tests included, with no new doc warnings. I also confirmed the unwrapped_functions.txt cleanup is accurate — every removed entry is genuinely wrapped.

One real bug and a few smaller items before merge:

Bug: get_metadata misreads the NVML contract

nvmlVgpuInstanceGetMetadata returns one variable-length structure, and bufferSize is in bytes — per the header: "The caller passes in a buffer via vgpuMetadata, with the size of the buffer in bufferSize", and INSUFFICIENT_SIZE reports the required byte count. The current code treats that byte count as an element count:

  • it allocates bufferSize copies of nvmlVgpuMetadata_t (~192 bytes each — a ~2KB requirement becomes a ~400KB allocation), and
  • converts every element, returning a Vec<VgpuMetadata> where only index 0 is real. The garbage entries convert successfully (zeroed guestInfoState is the valid Uninitialized variant), so callers silently get plausible-looking bogus entries.

This should return a single VgpuMetadata, allocating ceil(bytes / size_of::<nvmlVgpuMetadata_t>()) structs and reading only the first. (Non-blocking: the wrapper drops opaqueData, which future nvmlGetVgpuCompatibility support would need — fine to leave for later.)

Naming / API items

  • get_get_placement_id and get_get_runtime_state_size — doubled get_ typos.
  • The get_ prefixes generally diverge from the crate convention (name(), license(), frame_rate_limit() on these same types) — please drop them.
  • get_instance_type(&'dev self) over-constrains the borrow; &self works.
  • active_vgpus's <'a> ... where 'a: 'nvml clause is unnecessary — I verified locally that pub fn active_vgpus(&self) -> Result<Vec<VgpuInstance<'_>>, NvmlError> compiles (tests included), since Device is covariant in 'nvml.
  • VgpuInstance::new is pub(crate) and only called from the Linux-gated active_vgpus, so non-Linux builds emit a dead-code warning (and VgpuInstance is unconstructable on Windows) — needs a cfg or a constructor story.

Non-blocking notes

  • The active_vgpus return-type change is the right design but breaking — we'll release it as 0.13 with a changelog entry.
  • The new struct_wrappers/vgpu.rs types are missing the serde cfg_attr derives the other struct wrappers have, and VgpuLicenseState's hand-written From<u32> with a silent Unknown fallback diverges from the EnumWrapper/TryFrom convention used elsewhere.
  • convert_c_str decodes bytes as Latin-1 and maps stray negative bytes to NvmlError::Unknown — the crate's usual CStr + to_str() pattern would be more consistent.
  • VgpuLicenseExpiry silently saturates u32 fields to u8::MAX/u16::MAX.
  • Cosmetic: get_driver_version uses NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE where the header points at NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE (both 80, so harmless).

Happy to merge once the get_metadata fix and the naming items are in. Thanks again — the coverage expansion and the docs are much appreciated.

@FreeMasen

Copy link
Copy Markdown
Contributor Author

Thank you very much for your detailed review! I will address your comments as soon as I can

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants