nvml_wrapper/vgpu.rs
1use std::{
2 ffi::CStr,
3 os::raw::{c_char, c_uint},
4};
5
6use ffi::bindings::{
7 nvmlEnableState_enum_NVML_FEATURE_ENABLED, nvmlEncoderSessionInfo_t, nvmlFBCSessionInfo_t,
8 nvmlFBCStats_t, nvmlVgpuCapability_t, nvmlVgpuInstance_t, nvmlVgpuLicenseInfo_st,
9 nvmlVgpuMetadata_t, nvmlVgpuPlacementId_t, nvmlVgpuRuntimeState_t, nvmlVgpuTypeBar1Info_v1_t,
10 nvmlVgpuTypeId_t, nvmlVgpuVmIdType_NVML_VGPU_VM_ID_DOMAIN_ID,
11 nvmlVgpuVmIdType_NVML_VGPU_VM_ID_UUID, NVML_DEVICE_NAME_BUFFER_SIZE,
12 NVML_DEVICE_UUID_BUFFER_SIZE, NVML_GRID_LICENSE_BUFFER_SIZE,
13 NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE,
14};
15use static_assertions::assert_impl_all;
16
17use crate::{
18 enum_wrappers::vgpu::VmId,
19 error::{nvml_sym, nvml_try, nvml_try_count, NvmlError},
20 struct_wrappers::{
21 device::{EncoderSessionInfo, FbcSessionInfo, FbcStats},
22 vgpu::{Bar1Info, VgpuLicenseInfo, VgpuMetadata, VgpuPlacementId, VgpuRuntimeState},
23 },
24 structs::device::EncoderStats,
25 Device,
26};
27
28#[derive(Debug)]
29pub struct VgpuType<'dev> {
30 id: nvmlVgpuTypeId_t,
31 device: &'dev Device<'dev>,
32}
33
34assert_impl_all!(VgpuType: Send, Sync);
35
36impl<'dev> VgpuType<'dev> {
37 /// Create a new vGPU type wrapper.
38 ///
39 /// You probably don't need to use this yourself, but rather through
40 /// [`Device::vgpu_supported_types`] and [`Device::vgpu_creatable_types`].
41 pub fn new(device: &'dev Device, id: nvmlVgpuTypeId_t) -> Self {
42 Self { id, device }
43 }
44
45 /// Access the `Device` this struct belongs to.
46 ///
47 pub fn device(&self) -> &'dev Device<'_> {
48 self.device
49 }
50
51 /// Get the underlying vGPU type id.
52 pub fn id(&self) -> nvmlVgpuTypeId_t {
53 self.id
54 }
55
56 /// Retrieve the class of the vGPU type.
57 ///
58 /// # Errors
59 ///
60 /// * `Uninitialized`, if the library has not been successfully initialized
61 /// * `InvalidArg`, if this `Device` is invalid
62 /// * `Unknown`, on any unexpected error
63 ///
64 /// # Device support
65 ///
66 /// Kepler or newer fully supported devices.
67 #[doc(alias = "nvmlVgpuTypeGetClass")]
68 pub fn class_name(&self) -> Result<String, NvmlError> {
69 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuTypeGetClass.as_ref())?;
70
71 unsafe {
72 let mut size = NVML_DEVICE_NAME_BUFFER_SIZE;
73 let mut buffer = vec![0; size as usize];
74
75 nvml_try(sym(self.id, buffer.as_mut_ptr(), &mut size))?;
76
77 let version_raw = CStr::from_ptr(buffer.as_ptr());
78 Ok(version_raw.to_str()?.into())
79 }
80 }
81
82 /// Retrieve license requirements for a vGPU type.
83 ///
84 /// The license type and version required to run the specified vGPU type is returned as an
85 /// alphanumeric string, in the form "\<license name\>,\<version\>", for example
86 /// "GRID-Virtual-PC,2.0". If a vGPU is runnable with* more than one type of license, the
87 /// licenses are delimited by a semicolon, for example
88 /// "GRID-Virtual-PC,2.0;GRID-Virtual-WS,2.0;GRID-Virtual-WS-Ext,2.0".
89 ///
90 /// # Errors
91 ///
92 /// * `Uninitialized`, if the library has not been successfully initialized
93 /// * `InsufficientSize`, if the passed-in `size` is 0 (must be > 0)
94 /// * `InvalidArg`, if this `Device` is invalid
95 /// * `Unknown`, on any unexpected error
96 ///
97 /// # Device support
98 ///
99 /// Kepler or newer fully supported devices.
100 #[doc(alias = "nvmlVgpuTypeGetLicense")]
101 pub fn license(&self) -> Result<String, NvmlError> {
102 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuTypeGetLicense.as_ref())?;
103
104 unsafe {
105 let mut buffer = vec![0; NVML_GRID_LICENSE_BUFFER_SIZE as usize];
106
107 nvml_try(sym(self.id, buffer.as_mut_ptr(), buffer.len() as u32))?;
108
109 let version_raw = CStr::from_ptr(buffer.as_ptr());
110 Ok(version_raw.to_str()?.into())
111 }
112 }
113
114 /// Retrieve the name of the vGPU type.
115 ///
116 /// The name is an alphanumeric string that denotes a particular vGPU, e.g. GRID M60-2Q.
117 ///
118 /// # Errors
119 ///
120 /// * `Uninitialized`, if the library has not been successfully initialized
121 /// * `InvalidArg`, if this `Device` is invalid
122 /// * `Unknown`, on any unexpected error
123 ///
124 /// # Device support
125 ///
126 /// Kepler or newer fully supported devices.
127 #[doc(alias = "nvmlVgpuTypeGetName")]
128 pub fn name(&self) -> Result<String, NvmlError> {
129 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuTypeGetName.as_ref())?;
130
131 unsafe {
132 let mut size = NVML_DEVICE_NAME_BUFFER_SIZE;
133 let mut buffer = vec![0; size as usize];
134
135 nvml_try(sym(self.id, buffer.as_mut_ptr(), &mut size))?;
136
137 let version_raw = CStr::from_ptr(buffer.as_ptr());
138 Ok(version_raw.to_str()?.into())
139 }
140 }
141
142 /// Retrieve the requested capability for a given vGPU type. Refer to the
143 /// `nvmlVgpuCapability_t` structure for the specific capabilities that can be
144 /// queried.
145 ///
146 /// # Errors
147 ///
148 /// * `Uninitialized`, if the library has not been successfully initialized
149 /// * `InvalidArg`, if this `Device` is invalid
150 /// * `Unknown`, on any unexpected error
151 ///
152 /// # Device Support
153 ///
154 /// Maxwell or newer fully supported devices.
155 #[doc(alias = "nvmlVgpuTypeGetCapabilities")]
156 pub fn capabilities(&self, capability: nvmlVgpuCapability_t) -> Result<bool, NvmlError> {
157 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuTypeGetCapabilities.as_ref())?;
158
159 let mut result: c_uint = 0;
160 unsafe {
161 nvml_try(sym(self.id, capability, &mut result))?;
162 }
163 Ok(result != 0)
164 }
165
166 /// Retrieve the device ID of the vGPU type.
167 ///
168 /// # Errors
169 ///
170 /// * `Uninitialized`, if the library has not been successfully initialized
171 /// * `InvalidArg`, if this `Device` is invalid
172 /// * `Unknown`, on any unexpected error
173 ///
174 /// # Device Support
175 ///
176 /// Kepler or newer fully supported devices.
177 #[doc(alias = "nvmlVgpuTypeGetDeviceID")]
178 pub fn device_id(&self) -> Result<(u64, u64), NvmlError> {
179 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuTypeGetDeviceID.as_ref())?;
180
181 let (mut device_id, mut subsystem_id) = (0, 0);
182 unsafe {
183 nvml_try(sym(self.id, &mut device_id, &mut subsystem_id))?;
184 }
185 Ok((device_id, subsystem_id))
186 }
187
188 /// Retrieve the static frame rate limit value of the vGPU type.
189 ///
190 /// # Errors
191 ///
192 /// * `Uninitialized`, if the library has not been successfully initialized
193 /// * `NotSupported`, if frame rate limiter is turned off for the vGPU type
194 /// * `InvalidArg`, if this `Device` is invalid
195 /// * `Unknown`, on any unexpected error
196 ///
197 /// # Device Support
198 ///
199 /// Kepler or newer fully supported devices.
200 #[doc(alias = "nvmlVgpuTypeGetFrameRateLimit")]
201 pub fn frame_rate_limit(&self) -> Result<u32, NvmlError> {
202 let sym = nvml_sym(
203 self.device
204 .nvml()
205 .lib
206 .nvmlVgpuTypeGetFrameRateLimit
207 .as_ref(),
208 )?;
209
210 let mut limit = 0;
211 unsafe {
212 nvml_try(sym(self.id, &mut limit))?;
213 }
214 Ok(limit)
215 }
216
217 /// Retrieve the vGPU framebuffer size in bytes.
218 ///
219 /// # Errors
220 ///
221 /// * `Uninitialized`, if the library has not been successfully initialized
222 /// * `InvalidArg`, if this `Device` is invalid
223 /// * `Unknown`, on any unexpected error
224 ///
225 /// # Device Support
226 ///
227 /// Kepler or newer fully supported devices.
228 #[doc(alias = "nvmlVgpuTypeGetFramebufferSize")]
229 pub fn framebuffer_size(&self) -> Result<u64, NvmlError> {
230 let sym = nvml_sym(
231 self.device
232 .nvml()
233 .lib
234 .nvmlVgpuTypeGetFramebufferSize
235 .as_ref(),
236 )?;
237
238 let mut size = 0;
239 unsafe {
240 nvml_try(sym(self.id, &mut size))?;
241 }
242 Ok(size)
243 }
244
245 /// Retrieve the GPU Instance Profile ID for the vGPU type. The API will return a valid GPU
246 /// Instance Profile ID for the MIG capable vGPU types, else
247 /// [`crate::ffi::bindings::INVALID_GPU_INSTANCE_PROFILE_ID`] is returned.
248 ///
249 /// # Errors
250 ///
251 /// * `Uninitialized`, if the library has not been successfully initialized
252 /// * `InvalidArg`, if this `Device` is invalid
253 /// * `Unknown`, on any unexpected error
254 ///
255 /// # Device Support
256 ///
257 /// Kepler or newer fully supported devices.
258 #[doc(alias = "nvmlVgpuTypeGetGpuInstanceProfileId")]
259 pub fn instance_profile_id(&self) -> Result<u32, NvmlError> {
260 let sym = nvml_sym(
261 self.device
262 .nvml()
263 .lib
264 .nvmlVgpuTypeGetGpuInstanceProfileId
265 .as_ref(),
266 )?;
267
268 let mut profile_id = 0;
269 unsafe {
270 nvml_try(sym(self.id, &mut profile_id))?;
271 }
272 Ok(profile_id)
273 }
274
275 /// Retrieve the maximum number of vGPU instances creatable on a device for the vGPU type.
276 ///
277 /// # Errors
278 ///
279 /// * `Uninitialized`, if the library has not been successfully initialized
280 /// * `InvalidArg`, if this `Device` is invalid
281 /// * `Unknown`, on any unexpected error
282 ///
283 /// # Device Support
284 ///
285 /// Kepler or newer fully supported devices.
286 #[doc(alias = "nvmlVgpuTypeGetMaxInstances")]
287 pub fn max_instances(&self) -> Result<u32, NvmlError> {
288 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuTypeGetMaxInstances.as_ref())?;
289
290 let mut max = 0;
291 unsafe {
292 nvml_try(sym(self.device.handle(), self.id, &mut max))?;
293 }
294 Ok(max)
295 }
296
297 /// Retrieve the maximum number of vGPU instances supported per VM for the vGPU type.
298 ///
299 /// # Errors
300 ///
301 /// * `Uninitialized`, if the library has not been successfully initialized
302 /// * `InvalidArg`, if this `Device` is invalid
303 /// * `Unknown`, on any unexpected error
304 ///
305 /// # Device Support
306 ///
307 /// Kepler or newer fully supported devices.
308 #[doc(alias = "nvmlVgpuTypeGetMaxInstancesPerVm")]
309 pub fn max_instances_per_vm(&self) -> Result<u32, NvmlError> {
310 let sym = nvml_sym(
311 self.device
312 .nvml()
313 .lib
314 .nvmlVgpuTypeGetMaxInstancesPerVm
315 .as_ref(),
316 )?;
317
318 let mut max = 0;
319 unsafe {
320 nvml_try(sym(self.id, &mut max))?;
321 }
322 Ok(max)
323 }
324
325 /// Retrieve count of vGPU's supported display heads.
326 ///
327 /// # Errors
328 ///
329 /// * `Uninitialized`, if the library has not been successfully initialized
330 /// * `InvalidArg`, if this `Device` is invalid
331 /// * `Unknown`, on any unexpected error
332 ///
333 /// # Device Support
334 ///
335 /// Kepler or newer fully supported devices.
336 #[doc(alias = "nvmlVgpuTypeGetNumDisplayHeads")]
337 pub fn num_display_heads(&self) -> Result<u32, NvmlError> {
338 let sym = nvml_sym(
339 self.device
340 .nvml()
341 .lib
342 .nvmlVgpuTypeGetNumDisplayHeads
343 .as_ref(),
344 )?;
345
346 let mut heads = 0;
347 unsafe {
348 nvml_try(sym(self.id, &mut heads))?;
349 }
350 Ok(heads)
351 }
352
353 /// Retrieve vGPU display head's maximum supported resolution.
354 ///
355 /// The `display_head` argument specifies the 0-based display index, the
356 /// maximum being what [`VgpuType::num_display_heads`] returns.
357 ///
358 /// # Errors
359 ///
360 /// * `Uninitialized`, if the library has not been successfully initialized
361 /// * `InvalidArg`, if this `Device` is invalid
362 /// * `Unknown`, on any unexpected error
363 ///
364 /// # Device Support
365 ///
366 /// Kepler or newer fully supported devices.
367 #[doc(alias = "nvmlVgpuTypeGetResolution")]
368 pub fn resolution(&self, display_head: u32) -> Result<(u32, u32), NvmlError> {
369 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuTypeGetResolution.as_ref())?;
370
371 let (mut x, mut y) = (0, 0);
372 unsafe {
373 nvml_try(sym(self.id, display_head, &mut x, &mut y))?;
374 }
375 Ok((x, y))
376 }
377
378 /// Retrieve the BAR1 info for given vGPU type.
379 ///
380 /// # Errors
381 ///
382 /// * `Uninitialized`, if the library has not been successfully initialized
383 ///
384 /// # Platform Support
385 ///
386 /// For Maxwell or newer fully supported devices.
387 #[doc(alias = "nvmlVgpuTypeGetBAR1Info")]
388 pub fn bar1_info(&self) -> Result<Bar1Info, NvmlError> {
389 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuTypeGetBAR1Info.as_ref())?;
390 let mut info: nvmlVgpuTypeBar1Info_v1_t;
391 unsafe {
392 info = std::mem::zeroed();
393 nvml_try(sym(self.id, &mut info))?;
394 }
395 Ok(info.into())
396 }
397
398 /// Retrieve the static framebuffer reservation of the vGPU type in bytes
399 ///
400 /// # Errors
401 ///
402 /// * `Uninitialized`, if the library has not been successfully initialized
403 ///
404 #[doc(alias = "nvmlVgpuTypeGetFbReservation")]
405 pub fn fb_reservation(&self) -> Result<u64, NvmlError> {
406 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuTypeGetFbReservation.as_ref())?;
407 let mut res = 0;
408 unsafe {
409 nvml_try(sym(self.id, &mut res))?;
410 }
411 Ok(res)
412 }
413
414 /// Retrieve the static GSP heap size of the vGPU type in bytes
415 ///
416 /// # Errors
417 ///
418 /// * `Uninitialized`, if the library has not been successfully initialized
419 #[doc(alias = "nvmlVgpuTypeGetGspHeapSize")]
420 pub fn gsp_heap_size(&self) -> Result<u64, NvmlError> {
421 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuTypeGetGspHeapSize.as_ref())?;
422 let mut res = 0;
423 unsafe {
424 nvml_try(sym(self.id, &mut res))?;
425 }
426 Ok(res)
427 }
428}
429
430pub struct VgpuInstance<'dev> {
431 pub(crate) instance: nvmlVgpuInstance_t,
432 device: &'dev Device<'dev>,
433}
434
435assert_impl_all!(VgpuInstance: Send, Sync);
436
437impl<'dev> VgpuInstance<'dev> {
438 /// Create a new vGPU instance wrapper from a raw vGPU instance ID.
439 ///
440 /// You probably don't need to use this yourself, but rather through
441 /// `Device::active_vgpus` (Linux only).
442 pub fn new(instance: nvmlVgpuInstance_t, device: &'dev Device<'dev>) -> Self {
443 Self { instance, device }
444 }
445
446 /// Retrieve the VM ID associated with a vGPU instance.
447 ///
448 /// The VM ID is returned as a string, not exceeding 80 characters in length (including the NUL
449 /// terminator). See nvmlConstants::NVML_DEVICE_UUID_BUFFER_SIZE.
450 ///
451 /// The format of the VM ID varies by platform, and is indicated by the type identifier returned
452 /// in vmIdType.
453 ///
454 /// # Errors
455 ///
456 /// * `Uninitialized` if the library has not been successfully initialized
457 /// * `NotFound` if self does not match a valid active vGPU instance on the system
458 /// * `Unknown` on any unexpected error
459 ///
460 /// # Platform Support
461 ///
462 /// For Kepler or newer fully supported devices.
463 #[doc(alias = "nvmlVgpuInstanceGetVmID")]
464 pub fn vm_id(&self) -> Result<VmId, NvmlError> {
465 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuInstanceGetVmID.as_ref())?;
466 let mut s = [0; NVML_DEVICE_UUID_BUFFER_SIZE as usize];
467 let mut id_type = 0;
468 let id = unsafe {
469 nvml_try(sym(
470 self.instance,
471 s.as_mut_ptr(),
472 NVML_DEVICE_UUID_BUFFER_SIZE,
473 &mut id_type,
474 ))?;
475 CStr::from_ptr(s.as_ptr())
476 };
477
478 let id = id.to_str()?.to_string();
479 Ok(match id_type {
480 nvmlVgpuVmIdType_NVML_VGPU_VM_ID_DOMAIN_ID => VmId::Domain(id),
481 nvmlVgpuVmIdType_NVML_VGPU_VM_ID_UUID => VmId::Uuid(id),
482 _ => return Err(NvmlError::Unknown),
483 })
484 }
485
486 /// Retrieve the framebuffer usage in bytes.
487 ///
488 /// Framebuffer usage is the amount of vGPU framebuffer memory that is currently in use by the VM
489 ///
490 /// # Errors
491 ///
492 /// * `Uninitialized`, if the library has not been successfully initialized
493 /// * `InvalidArg` if self is invalid
494 /// * `NotFound` if self does not match a valid active vGPU instance on the system
495 /// * `Unknown`, on any unexpected error
496 ///
497 /// # Platform Support
498 ///
499 /// For Kepler or newer fully supported devices.
500 #[doc(alias = "nvmlVgpuInstanceGetFbUsage")]
501 pub fn fb_usage(&self) -> Result<u64, NvmlError> {
502 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuInstanceGetFbUsage.as_ref())?;
503 let mut usage = 0;
504 unsafe {
505 nvml_try(sym(self.instance, &mut usage))?;
506 }
507 Ok(usage)
508 }
509
510 /// Retrieve the vGPU type of a vGPU instance
511 ///
512 /// Returns the vGPU type ID of vgpu assigned to the vGPU instance.
513 ///
514 /// # Errors
515 ///
516 /// * `Uninitialized`, if the library has not been successfully initialized
517 /// * `InvalidArg` if self is invalid
518 /// * `NotFound` if self does not match a valid active vGPU instance on the system
519 /// * `Unknown`, on any unexpected error
520 ///
521 /// # Platform Support
522 ///
523 /// For Maxwell or newer fully supported devices
524 #[doc(alias = "nvmlVgpuInstanceGetType")]
525 pub fn instance_type(&self) -> Result<VgpuType<'dev>, NvmlError> {
526 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuInstanceGetType.as_ref())?;
527 let mut raw_type = 0;
528 unsafe {
529 nvml_try(sym(self.instance, &mut raw_type))?;
530 }
531 Ok(VgpuType::new(self.device, raw_type))
532 }
533
534 /// Get the list of process ids running on this vGPU instance for stats purpose
535 ///
536 /// see [`crate::device::Device::vgpu_accounting_pids`] for details
537 #[doc(alias = "nvmlVgpuInstanceGetAccountingPids")]
538 pub fn accounting_pids(&self) -> Result<Vec<u32>, NvmlError> {
539 self.device.vgpu_accounting_pids(self.instance)
540 }
541
542 /// Clears accounting information of the vGPU instance that have already terminated.
543 ///
544 /// # Errors
545 ///
546 /// * `Uninitialized`, if the library has not been successfully initialized
547 /// * `NoPermission`, if the user doesn't have permission to perform this operation
548 /// * `NotSupported`, if the vGPU doesn't support this feature or accounting mode is disabled
549 ///
550 /// # Platform Support
551 ///
552 /// For Maxwell or newer fully supported devices. Requires root/admin permissions.
553 #[doc(alias = "nvmlVgpuInstanceClearAccountingPids")]
554 pub fn clear_accounting_pids(&self) -> Result<(), NvmlError> {
555 let sym = nvml_sym(
556 self.device
557 .nvml()
558 .lib
559 .nvmlVgpuInstanceClearAccountingPids
560 .as_ref(),
561 )?;
562 unsafe { nvml_try(sym(self.instance)) }
563 }
564
565 /// Queries the state of per process accounting mode on vGPU.
566 ///
567 /// # Errors
568 ///
569 /// * `Uninitialized`, if the library has not been successfully initialized
570 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
571 /// * `NotSupported`, if the vGPU doesn't support this feature or accounting mode is disabled
572 /// * `DriverNotLoaded`, driver is not running on the vGPU instance
573 ///
574 /// # Platform Support
575 ///
576 /// For Maxwell or newer fully supported devices.
577 #[doc(alias = "nvmlVgpuInstanceGetAccountingMode")]
578 pub fn accounting_mode(&self) -> Result<bool, NvmlError> {
579 let sym = nvml_sym(
580 self.device
581 .nvml()
582 .lib
583 .nvmlVgpuInstanceGetAccountingMode
584 .as_ref(),
585 )?;
586 let mut mode = 0;
587 unsafe {
588 nvml_try(sym(self.instance, &mut mode))?;
589 }
590 Ok(mode == nvmlEnableState_enum_NVML_FEATURE_ENABLED)
591 }
592
593 /// Retrieve the current ECC mode of vGPU instance.
594 ///
595 /// # Errors
596 ///
597 /// * `Uninitialized`, if the library has not been successfully initialized
598 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
599 /// * `NotSupported`, if the vGPU doesn't support this feature or accounting mode is disabled
600 #[doc(alias = "nvmlVgpuInstanceGetEccMode")]
601 pub fn ecc_mode(&self) -> Result<bool, NvmlError> {
602 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuInstanceGetEccMode.as_ref())?;
603 let mut mode = 0;
604 unsafe {
605 nvml_try(sym(self.instance, &mut mode))?;
606 }
607 Ok(mode == nvmlEnableState_enum_NVML_FEATURE_ENABLED)
608 }
609
610 /// Retrieve the encoder capacity of a vGPU instance, as a percentage of maximum encoder
611 /// capacity with valid values in the range 0-100.
612 ///
613 /// # Errors
614 ///
615 /// * `Uninitialized`, if the library has not been successfully initialized
616 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
617 ///
618 /// # Platform Support
619 ///
620 /// For Maxwell or newer fully supported devices.
621 #[doc(alias = "nvmlVgpuInstanceGetEncoderCapacity")]
622 pub fn encoder_capacity(&self) -> Result<u32, NvmlError> {
623 let sym = nvml_sym(
624 self.device
625 .nvml()
626 .lib
627 .nvmlVgpuInstanceGetEncoderCapacity
628 .as_ref(),
629 )?;
630 let mut cap = 0;
631 unsafe {
632 nvml_try(sym(self.instance, &mut cap))?;
633 }
634 Ok(cap)
635 }
636
637 /// Retrieves information about all active encoder sessions on a vGPU Instance.
638 ///
639 /// # Errors
640 ///
641 /// * `Uninitialized`, if the library has not been successfully initialized
642 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
643 ///
644 /// # Platform Support
645 ///
646 /// For Maxwell or newer fully supported devices.
647 #[doc(alias = "nvmlVgpuInstanceGetEncoderSessions")]
648 pub fn encoder_sessions(&self) -> Result<Vec<EncoderSessionInfo>, NvmlError> {
649 let sym = nvml_sym(
650 self.device
651 .nvml()
652 .lib
653 .nvmlVgpuInstanceGetEncoderSessions
654 .as_ref(),
655 )?;
656 let mut count = self.encoder_session_count()?;
657 let mut raw_sessions: Vec<nvmlEncoderSessionInfo_t>;
658 unsafe {
659 raw_sessions = vec![std::mem::zeroed(); count as usize];
660 nvml_try(sym(self.instance, &mut count, raw_sessions.as_mut_ptr()))?;
661 };
662 raw_sessions
663 .into_iter()
664 .map(EncoderSessionInfo::try_from)
665 .collect()
666 }
667
668 /// Retrieves the current encoder statistics of a vGPU Instance
669 ///
670 /// # Errors
671 ///
672 /// * `Uninitialized`, if the library has not been successfully initialized
673 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
674 ///
675 /// # Platform Support
676 ///
677 /// For Maxwell or newer fully supported devices.
678 #[doc(alias = "nvmlVgpuInstanceGetEncoderStats")]
679 pub fn encoder_stats(&self) -> Result<EncoderStats, NvmlError> {
680 let sym = nvml_sym(
681 self.device
682 .nvml()
683 .lib
684 .nvmlVgpuInstanceGetEncoderStats
685 .as_ref(),
686 )?;
687 let mut session_count = self.encoder_session_count()?;
688 let mut average_fps = 0;
689 let mut average_latency = 0;
690 unsafe {
691 nvml_try(sym(
692 self.instance,
693 &mut session_count,
694 &mut average_fps,
695 &mut average_latency,
696 ))?;
697 };
698 Ok(EncoderStats {
699 session_count,
700 average_fps,
701 average_latency,
702 })
703 }
704
705 /// Retrieves information about active frame buffer capture sessions on a vGPU Instance.
706 ///
707 /// > hResolution, vResolution, averageFPS and averageLatency data for a FBC session
708 /// > returned in sessionInfo may be zero if there are no new frames captured since the
709 /// > session started.
710 ///
711 /// # Errors
712 ///
713 /// * `Uninitialized`, if the library has not been successfully initialized
714 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
715 ///
716 /// # Platform Support
717 ///
718 /// For Maxwell or newer fully supported devices.
719 #[doc(alias = "nvmlVgpuInstanceGetFBCSessions")]
720 pub fn fbc_sessions(&self) -> Result<Vec<FbcSessionInfo>, NvmlError> {
721 let sym = nvml_sym(
722 self.device
723 .nvml()
724 .lib
725 .nvmlVgpuInstanceGetFBCSessions
726 .as_ref(),
727 )?;
728 let mut session_count = 0;
729 let mut info: Vec<nvmlFBCSessionInfo_t>;
730 unsafe {
731 nvml_try_count(sym(self.instance, &mut session_count, std::ptr::null_mut()))?;
732 if session_count == 0 {
733 return Ok(Vec::new());
734 }
735 info = vec![std::mem::zeroed(); session_count as usize];
736 nvml_try(sym(self.instance, &mut session_count, info.as_mut_ptr()))?;
737 };
738 info.into_iter().map(FbcSessionInfo::try_from).collect()
739 }
740
741 /// Retrieves the active frame buffer capture sessions statistics of a vGPU Instance
742 ///
743 /// # Errors
744 ///
745 /// * `Uninitialized`, if the library has not been successfully initialized
746 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
747 ///
748 /// # Platform Support
749 ///
750 /// For Maxwell or newer fully supported devices.
751 #[doc(alias = "nvmlVgpuInstanceGetFBCStats")]
752 pub fn fbc_stats(&self) -> Result<FbcStats, NvmlError> {
753 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuInstanceGetFBCStats.as_ref())?;
754 unsafe {
755 let mut info: nvmlFBCStats_t = std::mem::zeroed();
756 nvml_try(sym(self.instance, &mut info))?;
757 Ok(FbcStats::from(info))
758 }
759 }
760
761 /// Retrieve the frame rate limit set for the vGPU instance.
762 ///
763 /// Returns the value of the frame rate limit set for the vGPU instance
764 ///
765 /// # Errors
766 ///
767 /// * `Uninitialized`, if the library has not been successfully initialized
768 /// * `NotSupported`, if frame rate limiter is turned off for the vGPU type
769 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
770 ///
771 /// # Platform Support
772 ///
773 /// For Kepler or newer fully supported devices.
774 #[doc(alias = "nvmlVgpuInstanceGetFrameRateLimit")]
775 pub fn frame_rate_limit(&self) -> Result<u32, NvmlError> {
776 let sym = nvml_sym(
777 self.device
778 .nvml()
779 .lib
780 .nvmlVgpuInstanceGetFrameRateLimit
781 .as_ref(),
782 )?;
783 let mut limit = 0;
784 unsafe {
785 nvml_try(sym(self.instance, &mut limit))?;
786 };
787 Ok(limit)
788 }
789
790 /// Retrieve the GPU Instance ID for the given vGPU Instance. The API will return a valid GPU
791 /// Instance ID for MIG backed vGPU Instance, else INVALID_GPU_INSTANCE_ID is returned.
792 ///
793 /// # Errors
794 ///
795 /// * `Uninitialized`, if the library has not been successfully initialized
796 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
797 ///
798 /// # Platform Support
799 ///
800 /// For Kepler or newer fully supported devices.
801 #[doc(alias = "nvmlVgpuInstanceGetGpuInstanceId")]
802 pub fn gpu_instance_id(&self) -> Result<u32, NvmlError> {
803 let sym = nvml_sym(
804 self.device
805 .nvml()
806 .lib
807 .nvmlVgpuInstanceGetGpuInstanceId
808 .as_ref(),
809 )?;
810 let mut id = 0;
811 unsafe {
812 nvml_try(sym(self.instance, &mut id))?;
813 };
814 Ok(id)
815 }
816
817 /// Retrieves the PCI Id of the given vGPU Instance i.e. the PCI Id of the GPU as seen inside
818 /// the VM.
819 ///
820 /// The vGPU PCI id is returned as "00000000:00:00.0" if NVIDIA driver is not installed on the
821 /// vGPU instance.
822 ///
823 /// # Errors
824 ///
825 /// * `Uninitialized`, if the library has not been successfully initialized
826 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
827 /// * `DriverNotLoaded`, driver is not running on the vGPU instance
828 #[doc(alias = "nvmlVgpuInstanceGetGpuPciId")]
829 pub fn gpu_pci_id(&self) -> Result<String, NvmlError> {
830 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuInstanceGetGpuPciId.as_ref())?;
831 let mut buffer: Vec<c_char>;
832 let mut count = 0;
833 let raw_id = unsafe {
834 nvml_try_count(sym(self.instance, [0; 1].as_mut_ptr(), &mut count))?;
835 if count == 0 {
836 return Ok(String::new());
837 }
838 buffer = vec![0; count as usize];
839 nvml_try(sym(self.instance, buffer.as_mut_ptr(), &mut count))?;
840 CStr::from_ptr(buffer.as_ptr())
841 };
842 Ok(raw_id.to_str()?.to_string())
843 }
844
845 /// Query the license information of the vGPU instance.
846 ///
847 /// # Errors
848 ///
849 /// * `Uninitialized`, if the library has not been successfully initialized
850 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
851 /// * `DriverNotLoaded`, driver is not running on the vGPU instance
852 #[cfg(feature = "legacy-functions")]
853 #[doc(alias = "nvmlVgpuInstanceGetLicenseInfo")]
854 pub fn license_info(&self) -> Result<VgpuLicenseInfo, NvmlError> {
855 let sym = nvml_sym(
856 self.device
857 .nvml()
858 .lib
859 .nvmlVgpuInstanceGetLicenseInfo
860 .as_ref(),
861 )?;
862 let mut info: nvmlVgpuLicenseInfo_st;
863
864 unsafe {
865 info = std::mem::zeroed();
866 nvml_try(sym(self.instance, &mut info))?;
867 };
868 Ok(VgpuLicenseInfo::from(info))
869 }
870
871 /// Query the license information of the vGPU instance.
872 ///
873 /// # Errors
874 ///
875 /// * `Uninitialized`, if the library has not been successfully initialized
876 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
877 /// * `DriverNotLoaded`, driver is not running on the vGPU instance
878 ///
879 /// # Platform Support
880 ///
881 /// For Maxwell or newer fully supported devices.
882 #[doc(alias = "nvmlVgpuInstanceGetLicenseInfo_v2")]
883 pub fn license_info_v2(&self) -> Result<VgpuLicenseInfo, NvmlError> {
884 let sym = nvml_sym(
885 self.device
886 .nvml()
887 .lib
888 .nvmlVgpuInstanceGetLicenseInfo_v2
889 .as_ref(),
890 )?;
891 let mut info: nvmlVgpuLicenseInfo_st;
892
893 unsafe {
894 info = std::mem::zeroed();
895 nvml_try(sym(self.instance, &mut info))?;
896 };
897 Ok(VgpuLicenseInfo::from(info))
898 }
899
900 /// Retrieve the MDEV UUID of a vGPU instance.
901 ///
902 /// The MDEV UUID is a globally unique identifier of the mdev device assigned to the VM, and is
903 /// returned as a 5-part hexadecimal string, not exceeding 80 characters in length (including
904 /// the NULL terminator). MDEV UUID is displayed only on KVM platform.
905 /// See nvmlConstants::NVML_DEVICE_UUID_BUFFER_SIZE.
906 ///
907 /// # Errors
908 ///
909 /// * `Uninitialized`, if the library has not been successfully initialized
910 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
911 /// * `NotSupported`, on any hypervisor other than KVM
912 ///
913 /// # Platform Support
914 ///
915 /// For Maxwell or newer fully supported devices.
916 #[doc(alias = "nvmlVgpuInstanceGetMdevUUID")]
917 pub fn mdev_uuid(&self) -> Result<String, NvmlError> {
918 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuInstanceGetMdevUUID.as_ref())?;
919 let mut buffer: [c_char; NVML_DEVICE_UUID_BUFFER_SIZE as usize] =
920 [0; NVML_DEVICE_UUID_BUFFER_SIZE as usize];
921
922 unsafe {
923 nvml_try(sym(
924 self.instance,
925 buffer.as_mut_ptr(),
926 NVML_DEVICE_UUID_BUFFER_SIZE,
927 ))?;
928 let raw_id = CStr::from_ptr(buffer.as_ptr());
929 Ok(raw_id.to_str()?.to_string())
930 }
931 }
932
933 /// Returns vGPU metadata structure for a running vGPU. The structure contains information
934 /// about the vGPU and its associated VM such as the currently installed NVIDIA guest driver
935 /// version, together with host driver version and an opaque data section containing internal
936 /// state.
937 ///
938 /// May be called at any time for a vGPU instance. Some fields in the returned structure are
939 /// dependent on information obtained from the guest VM, which may not yet have reached a state
940 /// where that information is available.
941 ///
942 /// # Errors
943 ///
944 /// * `Uninitialized`, if the library has not been successfully initialized
945 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
946 ///
947 /// # Platform Support
948 ///
949 ///
950 #[doc(alias = "nvmlVgpuInstanceGetMetadata")]
951 pub fn metadata(&self) -> Result<VgpuMetadata, NvmlError> {
952 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuInstanceGetMetadata.as_ref())?;
953 let mut byte_size = 0;
954 unsafe {
955 nvml_try_count(sym(self.instance, std::ptr::null_mut(), &mut byte_size))?;
956 // The metadata is one variable-length structure: a fixed header
957 // followed by an opaque payload. Over-allocate in whole
958 // `nvmlVgpuMetadata_t`s so the buffer stays correctly aligned.
959 let struct_size = std::mem::size_of::<nvmlVgpuMetadata_t>();
960 let count = ((byte_size as usize + struct_size - 1) / struct_size).max(1);
961 let mut buffer: Vec<nvmlVgpuMetadata_t> = vec![std::mem::zeroed(); count];
962 let mut byte_size = (count * struct_size) as c_uint;
963 nvml_try(sym(self.instance, buffer.as_mut_ptr(), &mut byte_size))?;
964 VgpuMetadata::try_from(buffer[0])
965 }
966 }
967
968 /// Query the placement ID of active vGPU instance.
969 ///
970 /// When in vGPU heterogeneous mode, this function returns a valid placement ID as
971 /// [`VgpuPlacementId::id`], [`VgpuPlacementId::version`] is the version number
972 /// # Errors
973 ///
974 /// * `Uninitialized`, if the library has not been successfully initialized
975 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
976 #[doc(alias = "nvmlVgpuInstanceGetPlacementId")]
977 pub fn placement_id(&self) -> Result<VgpuPlacementId, NvmlError> {
978 let sym = nvml_sym(
979 self.device
980 .nvml()
981 .lib
982 .nvmlVgpuInstanceGetPlacementId
983 .as_ref(),
984 )?;
985 let mut raw_placement_id: nvmlVgpuPlacementId_t;
986 unsafe {
987 raw_placement_id = std::mem::zeroed();
988 nvml_try(sym(self.instance, &mut raw_placement_id))?;
989 }
990 Ok(raw_placement_id.into())
991 }
992
993 /// Retrieve the currently used runtime state size of the vGPU instance
994 ///
995 /// This size represents the maximum in-memory data size utilized by a vGPU instance during
996 /// standard operation. This measurement is exclusive of frame buffer (FB) data size assigned
997 /// to the vGPU instance.
998 ///
999 /// # Errors
1000 ///
1001 /// * `Uninitialized`, if the library has not been successfully initialized
1002 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
1003 ///
1004 /// # Platform Support
1005 ///
1006 /// For Maxwell or newer fully supported devices.
1007 #[doc(alias = "nvmlVgpuInstanceGetRuntimeStateSize")]
1008 pub fn runtime_state_size(&self) -> Result<VgpuRuntimeState, NvmlError> {
1009 let sym = nvml_sym(
1010 self.device
1011 .nvml()
1012 .lib
1013 .nvmlVgpuInstanceGetRuntimeStateSize
1014 .as_ref(),
1015 )?;
1016 let mut raw_state: nvmlVgpuRuntimeState_t;
1017 unsafe {
1018 raw_state = std::mem::zeroed();
1019 nvml_try(sym(self.instance, &mut raw_state))?;
1020 }
1021 Ok(raw_state.into())
1022 }
1023
1024 /// Retrieve the UUID of a vGPU instance.
1025 ///
1026 /// The UUID is a globally unique identifier associated with the vGPU, and is returned as a 5-part hexadecimal string
1027 ///
1028 /// # Errors
1029 ///
1030 /// * `Uninitialized`, if the library has not been successfully initialized
1031 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
1032 ///
1033 /// # Platform Support
1034 ///
1035 /// For Kepler or newer fully supported devices.
1036 #[doc(alias = "nvmlVgpuInstanceGetUUID")]
1037 pub fn uuid(&self) -> Result<String, NvmlError> {
1038 let sym = nvml_sym(self.device.nvml().lib.nvmlVgpuInstanceGetUUID.as_ref())?;
1039 let mut buffer: [c_char; NVML_DEVICE_UUID_BUFFER_SIZE as usize] =
1040 [0; NVML_DEVICE_UUID_BUFFER_SIZE as usize];
1041
1042 unsafe {
1043 nvml_try(sym(
1044 self.instance,
1045 buffer.as_mut_ptr(),
1046 NVML_DEVICE_UUID_BUFFER_SIZE,
1047 ))?;
1048 let raw_id = CStr::from_ptr(buffer.as_ptr());
1049 Ok(raw_id.to_str()?.to_string())
1050 }
1051 }
1052
1053 /// Retrieve the NVIDIA driver version installed in the VM associated with a vGPU.
1054 ///
1055 /// The version is returned as an alphanumeric string in the caller-supplied buffer version.
1056 /// This may be called at any time for a vGPU instance.
1057 ///
1058 /// The guest VM driver version is returned as "Not Available" if no NVIDIA driver is installed
1059 /// in the VM, or the VM has not yet booted to the point where the NVIDIA driver is loaded and
1060 /// initialized.
1061 ///
1062 /// # Errors
1063 ///
1064 /// * `Uninitialized`, if the library has not been successfully initialized
1065 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
1066 ///
1067 /// # Platform Support
1068 ///
1069 /// For Kepler or newer fully supported devices.
1070 #[doc(alias = "nvmlVgpuInstanceGetVmDriverVersion")]
1071 pub fn driver_version(&self) -> Result<String, NvmlError> {
1072 let sym = nvml_sym(
1073 self.device
1074 .nvml()
1075 .lib
1076 .nvmlVgpuInstanceGetVmDriverVersion
1077 .as_ref(),
1078 )?;
1079 let mut buffer: [c_char; NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE as usize] =
1080 [0; NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE as usize];
1081
1082 unsafe {
1083 nvml_try(sym(
1084 self.instance,
1085 buffer.as_mut_ptr(),
1086 NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE,
1087 ))?;
1088 let raw_id = CStr::from_ptr(buffer.as_ptr());
1089 Ok(raw_id.to_str()?.to_string())
1090 }
1091 }
1092 /// Set the encoder capacity of a vGPU instance, as a percentage of maximum encoder capacity with valid values in the range 0-100.
1093 ///
1094 /// # Errors
1095 ///
1096 /// * `Uninitialized`, if the library has not been successfully initialized
1097 /// * `NotFound`, if the vGPU does not match a valid active vGPU instance on the system
1098 ///
1099 /// # Platform Support
1100 ///
1101 /// For Maxwell or newer fully supported devices.
1102 #[doc(alias = "nvmlVgpuInstanceSetEncoderCapacity")]
1103 pub fn set_encoder_capacity(&self, capacity: u32) -> Result<(), NvmlError> {
1104 let sym = nvml_sym(
1105 self.device
1106 .nvml()
1107 .lib
1108 .nvmlVgpuInstanceSetEncoderCapacity
1109 .as_ref(),
1110 )?;
1111
1112 unsafe {
1113 nvml_try(sym(self.instance, capacity))?;
1114 }
1115 Ok(())
1116 }
1117
1118 fn encoder_session_count(&self) -> Result<u32, NvmlError> {
1119 let sym = nvml_sym(
1120 self.device
1121 .nvml()
1122 .lib
1123 .nvmlVgpuInstanceGetEncoderSessions
1124 .as_ref(),
1125 )?;
1126 let mut count = 0;
1127 unsafe {
1128 nvml_try_count(sym(self.instance, &mut count, std::ptr::null_mut()))?;
1129 };
1130 Ok(count)
1131 }
1132}
1133
1134impl<'dev> std::fmt::Debug for VgpuInstance<'dev> {
1135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1136 f.debug_struct("VgpuInstance")
1137 .field("instance", &self.instance)
1138 .finish_non_exhaustive()
1139 }
1140}
1141
1142#[cfg(test)]
1143mod tests {
1144 use super::*;
1145
1146 use crate::test_utils::*;
1147
1148 #[test]
1149 fn vgpu_type_class_name() {
1150 let nvml = nvml();
1151 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).class_name());
1152 }
1153
1154 #[test]
1155 fn vgpu_type_license() {
1156 let nvml = nvml();
1157 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).license());
1158 }
1159
1160 #[test]
1161 fn vgpu_type_name() {
1162 let nvml = nvml();
1163 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).name());
1164 }
1165
1166 #[test]
1167 fn vgpu_type_device_id() {
1168 let nvml = nvml();
1169 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).device_id());
1170 }
1171
1172 #[test]
1173 fn vgpu_type_frame_rate_limit() {
1174 let nvml = nvml();
1175 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).frame_rate_limit());
1176 }
1177
1178 #[test]
1179 fn vgpu_type_framebuffer_size() {
1180 let nvml = nvml();
1181 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).framebuffer_size());
1182 }
1183
1184 #[test]
1185 fn vgpu_type_instance_profile_id() {
1186 let nvml = nvml();
1187 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).instance_profile_id());
1188 }
1189
1190 #[test]
1191 fn vgpu_type_max_instances() {
1192 let nvml = nvml();
1193 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).max_instances());
1194 }
1195
1196 #[test]
1197 fn vgpu_type_max_instances_per_vm() {
1198 let nvml = nvml();
1199 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).max_instances_per_vm());
1200 }
1201
1202 #[test]
1203 fn vgpu_type_num_display_heads() {
1204 let nvml = nvml();
1205 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).num_display_heads());
1206 }
1207
1208 #[test]
1209 fn vgpu_type_resolution() {
1210 let nvml = nvml();
1211 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).resolution(1));
1212 }
1213
1214 #[test]
1215 fn vgpu_type_get_bar1_info() {
1216 let nvml = nvml();
1217 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).bar1_info());
1218 }
1219
1220 #[test]
1221 fn vgpu_type_get_fb_reservation() {
1222 let nvml = nvml();
1223 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).fb_reservation());
1224 }
1225
1226 #[test]
1227 fn vgpu_type_get_gsp_heap_size() {
1228 let nvml = nvml();
1229 test_with_device(1, &nvml, |dev| VgpuType::new(dev, 1).gsp_heap_size());
1230 }
1231
1232 #[test]
1233 fn vgpu_instance_get_vm_id() {
1234 let nvml = nvml();
1235 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).vm_id());
1236 }
1237
1238 #[test]
1239 fn vgpu_instance_get_fb_usage() {
1240 let nvml = nvml();
1241 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).fb_usage());
1242 }
1243
1244 #[test]
1245 fn vgpu_instance_get_instance_type() {
1246 let nvml = nvml();
1247 test_with_device(1, &nvml, |dev| {
1248 Ok(VgpuInstance::new(1, dev).instance_type()?.id)
1249 });
1250 }
1251
1252 #[test]
1253 fn vgpu_instance_accounting_pids() {
1254 let nvml = nvml();
1255 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).accounting_pids());
1256 }
1257
1258 #[test]
1259 fn vgpu_instance_clear_accounting_pids() {
1260 let nvml = nvml();
1261 test_with_device(1, &nvml, |dev| {
1262 VgpuInstance::new(1, dev).clear_accounting_pids()
1263 });
1264 }
1265
1266 #[test]
1267 fn vgpu_instance_get_accounting_mode() {
1268 let nvml = nvml();
1269 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).accounting_mode());
1270 }
1271
1272 #[test]
1273 fn vgpu_instance_get_ecc_mode() {
1274 let nvml = nvml();
1275 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).ecc_mode());
1276 }
1277
1278 #[test]
1279 fn vgpu_instance_get_encoder_capacity() {
1280 let nvml = nvml();
1281 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).encoder_capacity());
1282 }
1283
1284 #[test]
1285 fn vgpu_instance_get_encoder_sessions() {
1286 let nvml = nvml();
1287 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).encoder_sessions());
1288 }
1289
1290 #[test]
1291 fn vgpu_instance_get_encoder_stats() {
1292 let nvml = nvml();
1293 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).encoder_stats());
1294 }
1295
1296 #[test]
1297 fn vgpu_instance_get_fbc_sessions() {
1298 let nvml = nvml();
1299 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).fbc_sessions());
1300 }
1301
1302 #[test]
1303 fn vgpu_instance_get_fbc_stats() {
1304 let nvml = nvml();
1305 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).fbc_stats());
1306 }
1307
1308 #[test]
1309 fn vgpu_instance_get_frame_rate_limit() {
1310 let nvml = nvml();
1311 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).frame_rate_limit());
1312 }
1313
1314 #[test]
1315 fn vgpu_instance_get_gpu_instance_id() {
1316 let nvml = nvml();
1317 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).gpu_instance_id());
1318 }
1319
1320 #[test]
1321 fn vgpu_instance_get_gpu_pci_id() {
1322 let nvml = nvml();
1323 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).gpu_pci_id());
1324 }
1325
1326 #[test]
1327 #[cfg(feature = "legacy-functions")]
1328 fn vgpu_instance_get_license_info() {
1329 let nvml = nvml();
1330 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).license_info());
1331 }
1332
1333 #[test]
1334 fn vgpu_instance_get_license_info_v2() {
1335 let nvml = nvml();
1336 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).license_info_v2());
1337 }
1338
1339 #[test]
1340 fn vgpu_instance_get_mdev_uuid() {
1341 let nvml = nvml();
1342 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).mdev_uuid());
1343 }
1344
1345 #[test]
1346 fn vgpu_instance_get_metadata() {
1347 let nvml = nvml();
1348 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).metadata());
1349 }
1350
1351 #[test]
1352 fn vgpu_instance_get_placement_id() {
1353 let nvml = nvml();
1354 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).placement_id());
1355 }
1356
1357 #[test]
1358 fn vgpu_instance_get_runtime_state_size() {
1359 let nvml = nvml();
1360 test_with_device(1, &nvml, |dev| {
1361 VgpuInstance::new(1, dev).runtime_state_size()
1362 });
1363 }
1364
1365 #[test]
1366 fn vgpu_instance_get_uuid() {
1367 let nvml = nvml();
1368 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).uuid());
1369 }
1370
1371 #[test]
1372 fn vgpu_instance_get_driver_version() {
1373 let nvml = nvml();
1374 test_with_device(1, &nvml, |dev| VgpuInstance::new(1, dev).driver_version());
1375 }
1376
1377 #[test]
1378 fn vgpu_instance_set_encoder_capacity() {
1379 let nvml = nvml();
1380 test_with_device(1, &nvml, |dev| {
1381 VgpuInstance::new(1, dev).set_encoder_capacity(50)
1382 });
1383 }
1384}