Skip to main content

singe_nvml/
vgpu_type.rs

1#[allow(unused_imports)]
2use crate::error::Status;
3
4use singe_core::string_from_c_chars;
5use singe_nvml_sys as sys;
6
7use crate::{
8    device::Device,
9    error::Result,
10    try_ffi,
11    types::{
12        VgpuTypeBar1Info, VgpuTypeCapability, VgpuTypeDeviceId, VgpuTypeId, VgpuTypeResolution,
13    },
14    utility::struct_version,
15};
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18#[repr(transparent)]
19pub struct VgpuType(VgpuTypeId);
20
21impl VgpuType {
22    pub const fn from_id(id: VgpuTypeId) -> Self {
23        Self(id)
24    }
25
26    pub const fn id(self) -> VgpuTypeId {
27        self.0
28    }
29
30    /// Returns the class of a vGPU type.
31    /// It does not exceed 64 bytes including the terminating NUL byte.
32    /// This wrapper allocates the required NVML buffer internally.
33    ///
34    /// For Kepler or newer fully supported devices.
35    ///
36    /// # Errors
37    ///
38    /// Returns an error if the internal class-name buffer is too small, if
39    /// NVML rejects the vGPU type ID or query arguments, or if NVML reports an
40    /// unexpected failure.
41    pub fn class(self) -> Result<String> {
42        let mut buffer = [0i8; sys::NVML_VGPU_NAME_BUFFER_SIZE as usize];
43        let mut size = buffer.len() as u32;
44        unsafe {
45            try_ffi!(sys::nvmlVgpuTypeGetClass(
46                self.0.0,
47                buffer.as_mut_ptr(),
48                &raw mut size,
49            ))?;
50        }
51        Ok(string_from_c_chars(&buffer))
52    }
53
54    /// Returns the vGPU type name.
55    ///
56    /// The name is an alphanumeric vGPU identifier such as `GRID M60-2Q`.
57    /// It does not exceed 64 bytes including the terminating NUL byte.
58    /// This wrapper allocates the required NVML buffer internally.
59    ///
60    /// For Kepler or newer fully supported devices.
61    ///
62    /// # Errors
63    ///
64    /// Returns an error if the internal name buffer is too small, if NVML
65    /// rejects the vGPU type ID or query arguments, or if NVML reports an
66    /// unexpected failure.
67    pub fn name(self) -> Result<String> {
68        let mut buffer = [0i8; sys::NVML_VGPU_NAME_BUFFER_SIZE as usize];
69        let mut size = buffer.len() as u32;
70        unsafe {
71            try_ffi!(sys::nvmlVgpuTypeGetName(
72                self.0.0,
73                buffer.as_mut_ptr(),
74                &raw mut size,
75            ))?;
76        }
77        Ok(string_from_c_chars(&buffer))
78    }
79
80    /// Returns the GPU instance profile ID for this vGPU type ID.
81    /// Returns a valid GPU instance profile ID for MIG-capable vGPU types, or
82    /// `INVALID_GPU_INSTANCE_PROFILE_ID` otherwise.
83    ///
84    /// For Kepler or newer fully supported devices.
85    ///
86    /// # Errors
87    ///
88    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
89    /// if the device is not in vGPU host virtualization mode, or if NVML
90    /// reports an unexpected failure.
91    pub fn gpu_instance_profile_id(self) -> Result<u32> {
92        let mut profile_id = 0;
93        unsafe {
94            try_ffi!(sys::nvmlVgpuTypeGetGpuInstanceProfileId(
95                self.0.0,
96                &raw mut profile_id,
97            ))?;
98        }
99        Ok(profile_id)
100    }
101
102    /// Returns the device ID of a vGPU type.
103    ///
104    /// For Kepler or newer fully supported devices.
105    ///
106    /// # Errors
107    ///
108    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
109    /// if NVML has not been initialized, or if NVML reports an unexpected
110    /// failure.
111    pub fn device_id(self) -> Result<VgpuTypeDeviceId> {
112        let mut device_id = 0;
113        let mut subsystem_id = 0;
114        unsafe {
115            try_ffi!(sys::nvmlVgpuTypeGetDeviceID(
116                self.0.0,
117                &raw mut device_id,
118                &raw mut subsystem_id,
119            ))?;
120        }
121        Ok(VgpuTypeDeviceId {
122            device_id,
123            subsystem_id,
124        })
125    }
126
127    /// Returns the vGPU framebuffer size in bytes.
128    ///
129    /// For Kepler or newer fully supported devices.
130    ///
131    /// # Errors
132    ///
133    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
134    /// if NVML has not been initialized, or if NVML reports an unexpected
135    /// failure.
136    pub fn framebuffer_size(self) -> Result<u64> {
137        let mut size = 0;
138        unsafe {
139            try_ffi!(sys::nvmlVgpuTypeGetFramebufferSize(self.0.0, &raw mut size))?;
140        }
141        Ok(size)
142    }
143
144    /// Returns count of vGPU's supported display heads.
145    ///
146    /// For Kepler or newer fully supported devices.
147    ///
148    /// # Errors
149    ///
150    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
151    /// if NVML has not been initialized, or if NVML reports an unexpected
152    /// failure.
153    pub fn num_display_heads(self) -> Result<u32> {
154        let mut count = 0;
155        unsafe {
156            try_ffi!(sys::nvmlVgpuTypeGetNumDisplayHeads(
157                self.0.0,
158                &raw mut count
159            ))?;
160        }
161        Ok(count)
162    }
163
164    /// Returns vGPU display head's maximum supported resolution.
165    ///
166    /// For Kepler or newer fully supported devices.
167    ///
168    /// # Errors
169    ///
170    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
171    /// if NVML has not been initialized, or if NVML reports an unexpected
172    /// failure.
173    pub fn resolution(self, display_index: u32) -> Result<VgpuTypeResolution> {
174        let mut x = 0;
175        let mut y = 0;
176        unsafe {
177            try_ffi!(sys::nvmlVgpuTypeGetResolution(
178                self.0.0,
179                display_index,
180                &raw mut x,
181                &raw mut y,
182            ))?;
183        }
184        Ok(VgpuTypeResolution { x, y })
185    }
186
187    /// Returns license requirements for a vGPU type.
188    ///
189    /// The license type and version required to run the specified vGPU type is
190    /// returned as an alphanumeric string in the form `<license name>,<version>`,
191    /// for example `GRID-Virtual-PC,2.0`.
192    /// If a vGPU is runnable with more than one license type, the licenses are
193    /// delimited by semicolons, for example
194    /// `GRID-Virtual-PC,2.0;GRID-Virtual-WS,2.0;GRID-Virtual-WS-Ext,2.0`.
195    ///
196    /// The returned string does not exceed 128 bytes including the terminating
197    /// NUL byte.
198    /// This wrapper allocates the required NVML buffer internally.
199    ///
200    /// For Kepler or newer fully supported devices.
201    ///
202    /// # Errors
203    ///
204    /// Returns an error if the internal license buffer is too small, if NVML
205    /// rejects the vGPU type ID or query arguments, if NVML has not been
206    /// initialized, or if NVML reports an unexpected failure.
207    pub fn license(self) -> Result<String> {
208        let mut buffer = [0i8; sys::NVML_GRID_LICENSE_BUFFER_SIZE as usize];
209        unsafe {
210            try_ffi!(sys::nvmlVgpuTypeGetLicense(
211                self.0.0,
212                buffer.as_mut_ptr(),
213                buffer.len() as u32,
214            ))?;
215        }
216        Ok(string_from_c_chars(&buffer))
217    }
218
219    /// Returns the static frame-rate limit value of the vGPU type.
220    ///
221    /// For Kepler or newer fully supported devices.
222    ///
223    /// # Errors
224    ///
225    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
226    /// if the frame-rate limiter is disabled for this vGPU type, if NVML has
227    /// not been initialized, or if NVML reports an unexpected failure.
228    pub fn frame_rate_limit(self) -> Result<u32> {
229        let mut limit = 0;
230        unsafe {
231            try_ffi!(sys::nvmlVgpuTypeGetFrameRateLimit(self.0.0, &raw mut limit))?;
232        }
233        Ok(limit)
234    }
235
236    /// Returns the maximum number of vGPU instances creatable on a device for this vGPU type.
237    ///
238    /// For Kepler or newer fully supported devices.
239    ///
240    /// # Errors
241    ///
242    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
243    /// if NVML has not been initialized, or if NVML reports an unexpected
244    /// failure.
245    pub fn max_instances(self, device: Device) -> Result<u32> {
246        let mut count = 0;
247        unsafe {
248            try_ffi!(sys::nvmlVgpuTypeGetMaxInstances(
249                device.as_raw(),
250                self.0.0,
251                &raw mut count,
252            ))?;
253        }
254        Ok(count)
255    }
256
257    /// Returns the maximum number of vGPU instances supported per VM for this vGPU type.
258    ///
259    /// For Kepler or newer fully supported devices.
260    ///
261    /// # Errors
262    ///
263    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
264    /// if NVML has not been initialized, or if NVML reports an unexpected
265    /// failure.
266    pub fn max_instances_per_vm(self) -> Result<u32> {
267        let mut count = 0;
268        unsafe {
269            try_ffi!(sys::nvmlVgpuTypeGetMaxInstancesPerVm(
270                self.0.0,
271                &raw mut count,
272            ))?;
273        }
274        Ok(count)
275    }
276
277    /// Returns the maximum number of vGPU instances per GPU instance for this vGPU type.
278    ///
279    /// # Errors
280    ///
281    /// Returns an error if NVML rejects the versioned request, if the vGPU
282    /// type ID or query arguments are invalid, if the host, GPU, or vGPU type
283    /// does not support the query, if NVML has not been initialized, or if
284    /// NVML reports an unexpected failure.
285    pub fn max_instances_per_gpu_instance(self) -> Result<u32> {
286        let mut max_instance = sys::nvmlVgpuTypeMaxInstance_t {
287            version: struct_version::<sys::nvmlVgpuTypeMaxInstance_t>(1),
288            vgpuTypeId: self.0.0,
289            ..Default::default()
290        };
291        unsafe {
292            try_ffi!(sys::nvmlVgpuTypeGetMaxInstancesPerGpuInstance(
293                &raw mut max_instance
294            ))?;
295        }
296        Ok(max_instance.maxInstancePerGI)
297    }
298
299    /// Returns the BAR1 info for this vGPU type.
300    ///
301    /// For Maxwell or newer fully supported devices.
302    ///
303    /// # Errors
304    ///
305    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
306    /// if NVML has not been initialized, or if NVML reports an unexpected
307    /// failure.
308    pub fn bar1_info(self) -> Result<VgpuTypeBar1Info> {
309        let mut info = sys::nvmlVgpuTypeBar1Info_t {
310            version: 1 | ((size_of::<sys::nvmlVgpuTypeBar1Info_t>() as u32) << 16),
311            ..Default::default()
312        };
313        unsafe {
314            try_ffi!(sys::nvmlVgpuTypeGetBAR1Info(self.0.0, &raw mut info))?;
315        }
316        Ok(info.into())
317    }
318
319    /// Returns the requested capability for the given vGPU type.
320    /// See [`VgpuTypeCapability`] for the supported capabilities.
321    /// Returns a boolean indicating whether the capability is supported.
322    ///
323    /// For Maxwell or newer fully supported devices.
324    ///
325    /// # Errors
326    ///
327    /// Returns an error if NVML rejects the vGPU type ID, capability, or query
328    /// arguments, if NVML has not been initialized, or if NVML reports an
329    /// unexpected failure.
330    pub fn capability(self, capability: VgpuTypeCapability) -> Result<bool> {
331        let mut result = 0;
332        unsafe {
333            try_ffi!(sys::nvmlVgpuTypeGetCapabilities(
334                self.0.0,
335                capability.into(),
336                &raw mut result,
337            ))?;
338        }
339        Ok(result != 0)
340    }
341
342    /// Returns the static framebuffer reservation of the vGPU type in bytes.
343    ///
344    /// # Errors
345    ///
346    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
347    /// if NVML has not been initialized, or if NVML reports an unexpected
348    /// failure.
349    pub fn fb_reservation(self) -> Result<u64> {
350        let mut reservation = 0;
351        unsafe {
352            try_ffi!(sys::nvmlVgpuTypeGetFbReservation(
353                self.0.0,
354                &raw mut reservation,
355            ))?;
356        }
357        Ok(reservation)
358    }
359
360    /// Returns the static GSP heap size of the vGPU type in bytes.
361    ///
362    /// # Errors
363    ///
364    /// Returns an error if NVML rejects the vGPU type ID or query arguments,
365    /// if NVML has not been initialized, or if NVML reports an unexpected
366    /// failure.
367    pub fn gsp_heap_size(self) -> Result<u64> {
368        let mut size = 0;
369        unsafe {
370            try_ffi!(sys::nvmlVgpuTypeGetGspHeapSize(self.0.0, &raw mut size))?;
371        }
372        Ok(size)
373    }
374}