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}