1use std::convert::TryFrom;
2use std::fmt::Display;
3use std::os::raw::c_uint;
4
5use crate::enum_wrappers::device::{ClockLimitId, SampleValueType};
6use crate::error::NvmlError;
7use crate::ffi::bindings::*;
8#[cfg(feature = "serde")]
9use serde_derive::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, Eq, PartialEq, Hash)]
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14pub enum FirmwareVersion {
15 Unavailable,
17 Version(u32),
18}
19
20impl From<u32> for FirmwareVersion {
21 fn from(value: u32) -> Self {
22 match value {
23 0 => FirmwareVersion::Unavailable,
24 _ => FirmwareVersion::Version(value),
25 }
26 }
27}
28
29#[derive(Debug, Clone, Eq, PartialEq, Hash)]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33pub enum UsedGpuMemory {
34 Unavailable,
37 Used(u64),
39}
40
41impl From<u64> for UsedGpuMemory {
42 fn from(value: u64) -> Self {
43 let not_available = (NVML_VALUE_NOT_AVAILABLE) as u64;
44
45 match value {
46 v if v == not_available => UsedGpuMemory::Unavailable,
47 _ => UsedGpuMemory::Used(value),
48 }
49 }
50}
51
52#[derive(Debug, Clone, PartialEq)]
55#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
56pub enum SampleValue {
57 F64(f64),
58 U32(u32),
59 U64(u64),
60 I64(i64),
61}
62
63impl SampleValue {
64 pub fn from_tag_and_union(tag: &SampleValueType, union: nvmlValue_t) -> Self {
65 use self::SampleValueType::*;
66
67 unsafe {
68 match *tag {
69 Double => SampleValue::F64(union.dVal),
70 UnsignedInt => SampleValue::U32(union.uiVal),
71 #[allow(clippy::unnecessary_cast)]
74 UnsignedLong => SampleValue::U32(union.ulVal as u32),
75 UnsignedLongLong => SampleValue::U64(union.ullVal),
76 SignedLongLong => SampleValue::I64(union.sllVal),
77 }
78 }
79 }
80}
81
82#[derive(Debug, Clone, Eq, PartialEq, Hash)]
84#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
85pub enum GpuLockedClocksSetting {
86 Numeric {
89 min_clock_mhz: u32,
90 max_clock_mhz: u32,
91 },
92 Symbolic {
99 lower_bound: ClockLimitId,
100 upper_bound: ClockLimitId,
101 },
102}
103
104impl GpuLockedClocksSetting {
105 pub fn into_min_and_max_clocks(self) -> (u32, u32) {
107 match self {
108 GpuLockedClocksSetting::Numeric {
109 min_clock_mhz,
110 max_clock_mhz,
111 } => (min_clock_mhz, max_clock_mhz),
112 GpuLockedClocksSetting::Symbolic {
113 lower_bound,
114 upper_bound,
115 } => (lower_bound.as_c(), upper_bound.as_c()),
116 }
117 }
118}
119
120#[derive(Debug, Clone, Eq, PartialEq, Hash)]
124#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
125pub enum BusType {
126 Unknown,
128 Pci,
130 Pcie,
134 Fpci,
136 Agp,
140}
141
142impl BusType {
143 pub fn as_c(&self) -> nvmlBusType_t {
145 match *self {
146 Self::Unknown => NVML_BUS_TYPE_UNKNOWN,
147 Self::Pci => NVML_BUS_TYPE_PCI,
148 Self::Pcie => NVML_BUS_TYPE_PCIE,
149 Self::Fpci => NVML_BUS_TYPE_FPCI,
150 Self::Agp => NVML_BUS_TYPE_AGP,
151 }
152 }
153}
154
155impl TryFrom<nvmlBusType_t> for BusType {
156 type Error = NvmlError;
157
158 fn try_from(data: nvmlBusType_t) -> Result<Self, Self::Error> {
159 match data {
160 NVML_BUS_TYPE_UNKNOWN => Ok(Self::Unknown),
161 NVML_BUS_TYPE_PCI => Ok(Self::Pci),
162 NVML_BUS_TYPE_PCIE => Ok(Self::Pcie),
163 NVML_BUS_TYPE_FPCI => Ok(Self::Fpci),
164 NVML_BUS_TYPE_AGP => Ok(Self::Agp),
165 _ => Err(NvmlError::UnexpectedVariant(data)),
166 }
167 }
168}
169
170#[derive(Debug, Clone, Eq, PartialEq, Hash)]
174#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
175pub enum PowerSource {
176 Ac,
178 Battery,
180}
181
182impl PowerSource {
183 pub fn as_c(&self) -> nvmlPowerSource_t {
185 match *self {
186 Self::Ac => NVML_POWER_SOURCE_AC,
187 Self::Battery => NVML_POWER_SOURCE_BATTERY,
188 }
189 }
190}
191
192impl TryFrom<nvmlPowerSource_t> for PowerSource {
193 type Error = NvmlError;
194
195 fn try_from(data: nvmlPowerSource_t) -> Result<Self, Self::Error> {
196 match data {
197 NVML_POWER_SOURCE_AC => Ok(Self::Ac),
198 NVML_POWER_SOURCE_BATTERY => Ok(Self::Battery),
199 _ => Err(NvmlError::UnexpectedVariant(data)),
200 }
201 }
202}
203
204#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
208#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
209pub enum PowerMizerMode {
210 Adaptive,
212 PreferMaximumPerformance,
214 Auto,
216 PreferConsistentPerformance,
218}
219
220impl PowerMizerMode {
221 pub fn as_c(&self) -> c_uint {
223 match *self {
224 Self::Adaptive => NVML_POWER_MIZER_MODE_ADAPTIVE,
225 Self::PreferMaximumPerformance => NVML_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE,
226 Self::Auto => NVML_POWER_MIZER_MODE_AUTO,
227 Self::PreferConsistentPerformance => {
228 NVML_POWER_MIZER_MODE_PREFER_CONSISTENT_PERFORMANCE
229 }
230 }
231 }
232}
233
234impl TryFrom<c_uint> for PowerMizerMode {
235 type Error = NvmlError;
236
237 fn try_from(data: c_uint) -> Result<Self, Self::Error> {
238 match data {
239 NVML_POWER_MIZER_MODE_ADAPTIVE => Ok(Self::Adaptive),
240 NVML_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE => Ok(Self::PreferMaximumPerformance),
241 NVML_POWER_MIZER_MODE_AUTO => Ok(Self::Auto),
242 NVML_POWER_MIZER_MODE_PREFER_CONSISTENT_PERFORMANCE => {
243 Ok(Self::PreferConsistentPerformance)
244 }
245 _ => Err(NvmlError::UnexpectedVariant(data)),
246 }
247 }
248}
249
250#[derive(Debug, Clone, Eq, PartialEq, Hash)]
256#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
257pub enum DeviceArchitecture {
258 Kepler,
260 Maxwell,
262 Pascal,
264 Volta,
266 Turing,
268 Ampere,
270 Ada,
272 Hopper,
274 Blackwell,
276 Unknown,
278}
279
280impl DeviceArchitecture {
281 pub fn as_c(&self) -> nvmlDeviceArchitecture_t {
283 match *self {
284 Self::Kepler => NVML_DEVICE_ARCH_KEPLER,
285 Self::Maxwell => NVML_DEVICE_ARCH_MAXWELL,
286 Self::Pascal => NVML_DEVICE_ARCH_PASCAL,
287 Self::Volta => NVML_DEVICE_ARCH_VOLTA,
288 Self::Turing => NVML_DEVICE_ARCH_TURING,
289 Self::Ampere => NVML_DEVICE_ARCH_AMPERE,
290 Self::Ada => NVML_DEVICE_ARCH_ADA,
291 Self::Hopper => NVML_DEVICE_ARCH_HOPPER,
292 Self::Blackwell => NVML_DEVICE_ARCH_BLACKWELL,
293 Self::Unknown => NVML_DEVICE_ARCH_UNKNOWN,
294 }
295 }
296}
297
298impl TryFrom<nvmlDeviceArchitecture_t> for DeviceArchitecture {
299 type Error = NvmlError;
300
301 fn try_from(data: nvmlDeviceArchitecture_t) -> Result<Self, Self::Error> {
302 match data {
303 NVML_DEVICE_ARCH_KEPLER => Ok(Self::Kepler),
304 NVML_DEVICE_ARCH_MAXWELL => Ok(Self::Maxwell),
305 NVML_DEVICE_ARCH_PASCAL => Ok(Self::Pascal),
306 NVML_DEVICE_ARCH_VOLTA => Ok(Self::Volta),
307 NVML_DEVICE_ARCH_TURING => Ok(Self::Turing),
308 NVML_DEVICE_ARCH_AMPERE => Ok(Self::Ampere),
309 NVML_DEVICE_ARCH_ADA => Ok(Self::Ada),
310 NVML_DEVICE_ARCH_HOPPER => Ok(Self::Hopper),
311 NVML_DEVICE_ARCH_BLACKWELL => Ok(Self::Blackwell),
312 NVML_DEVICE_ARCH_UNKNOWN => Ok(Self::Unknown),
313 _ => Err(NvmlError::UnexpectedVariant(data)),
314 }
315 }
316}
317
318impl Display for DeviceArchitecture {
319 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
320 match self {
321 Self::Kepler => f.write_str("Kepler"),
322 Self::Maxwell => f.write_str("Maxwell"),
323 Self::Pascal => f.write_str("Pascal"),
324 Self::Volta => f.write_str("Volta"),
325 Self::Turing => f.write_str("Turing"),
326 Self::Ampere => f.write_str("Ampere"),
327 Self::Ada => f.write_str("Ada"),
328 Self::Hopper => f.write_str("Hopper"),
329 Self::Blackwell => f.write_str("Blackwell"),
330 Self::Unknown => f.write_str("Unknown"),
331 }
332 }
333}
334
335#[derive(Debug, Clone, Eq, PartialEq, Hash)]
348#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
349pub enum PcieLinkMaxSpeed {
350 Invalid,
351 MegaTransfersPerSecond2500,
352 MegaTransfersPerSecond5000,
353 MegaTransfersPerSecond8000,
354 MegaTransfersPerSecond16000,
355 MegaTransfersPerSecond32000,
356}
357
358impl PcieLinkMaxSpeed {
359 pub fn as_integer(&self) -> Option<u32> {
361 Some(match self {
362 PcieLinkMaxSpeed::Invalid => return None,
363 PcieLinkMaxSpeed::MegaTransfersPerSecond2500 => 2500,
364 PcieLinkMaxSpeed::MegaTransfersPerSecond5000 => 5000,
365 PcieLinkMaxSpeed::MegaTransfersPerSecond8000 => 8000,
366 PcieLinkMaxSpeed::MegaTransfersPerSecond16000 => 16000,
367 PcieLinkMaxSpeed::MegaTransfersPerSecond32000 => 32000,
368 })
369 }
370
371 pub fn as_c(&self) -> c_uint {
373 match *self {
374 Self::Invalid => NVML_PCIE_LINK_MAX_SPEED_INVALID,
375 Self::MegaTransfersPerSecond2500 => NVML_PCIE_LINK_MAX_SPEED_2500MBPS,
376 Self::MegaTransfersPerSecond5000 => NVML_PCIE_LINK_MAX_SPEED_5000MBPS,
377 Self::MegaTransfersPerSecond8000 => NVML_PCIE_LINK_MAX_SPEED_8000MBPS,
378 Self::MegaTransfersPerSecond16000 => NVML_PCIE_LINK_MAX_SPEED_16000MBPS,
379 Self::MegaTransfersPerSecond32000 => NVML_PCIE_LINK_MAX_SPEED_32000MBPS,
380 }
381 }
382}
383
384impl TryFrom<c_uint> for PcieLinkMaxSpeed {
385 type Error = NvmlError;
386
387 fn try_from(data: c_uint) -> Result<Self, Self::Error> {
388 match data {
389 NVML_PCIE_LINK_MAX_SPEED_INVALID => Ok(Self::Invalid),
390 NVML_PCIE_LINK_MAX_SPEED_2500MBPS => Ok(Self::MegaTransfersPerSecond2500),
391 NVML_PCIE_LINK_MAX_SPEED_5000MBPS => Ok(Self::MegaTransfersPerSecond5000),
392 NVML_PCIE_LINK_MAX_SPEED_8000MBPS => Ok(Self::MegaTransfersPerSecond8000),
393 NVML_PCIE_LINK_MAX_SPEED_16000MBPS => Ok(Self::MegaTransfersPerSecond16000),
394 NVML_PCIE_LINK_MAX_SPEED_32000MBPS => Ok(Self::MegaTransfersPerSecond32000),
395 _ => Err(NvmlError::UnexpectedVariant(data)),
396 }
397 }
398}
399
400#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
401#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
402#[repr(u32)]
403pub enum FanControlPolicy {
404 TemperatureContinousSw = NVML_FAN_POLICY_TEMPERATURE_CONTINOUS_SW,
405 Manual = NVML_FAN_POLICY_MANUAL,
406}
407
408impl FanControlPolicy {
414 pub fn as_c(&self) -> nvmlFanControlPolicy_t {
415 *self as u32
416 }
417}
418
419impl TryFrom<nvmlFanControlPolicy_t> for FanControlPolicy {
420 type Error = NvmlError;
421
422 fn try_from(value: nvmlFanControlPolicy_t) -> Result<Self, Self::Error> {
423 match value {
424 NVML_FAN_POLICY_TEMPERATURE_CONTINOUS_SW => Ok(Self::TemperatureContinousSw),
425 NVML_FAN_POLICY_MANUAL => Ok(Self::Manual),
426 _ => Err(NvmlError::UnexpectedVariant(value)),
427 }
428 }
429}