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, Eq, PartialEq, Hash)]
210#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
211pub enum DeviceArchitecture {
212 Kepler,
214 Maxwell,
216 Pascal,
218 Volta,
220 Turing,
222 Ampere,
224 Ada,
226 Hopper,
228 Blackwell,
230 Unknown,
232}
233
234impl DeviceArchitecture {
235 pub fn as_c(&self) -> nvmlDeviceArchitecture_t {
237 match *self {
238 Self::Kepler => NVML_DEVICE_ARCH_KEPLER,
239 Self::Maxwell => NVML_DEVICE_ARCH_MAXWELL,
240 Self::Pascal => NVML_DEVICE_ARCH_PASCAL,
241 Self::Volta => NVML_DEVICE_ARCH_VOLTA,
242 Self::Turing => NVML_DEVICE_ARCH_TURING,
243 Self::Ampere => NVML_DEVICE_ARCH_AMPERE,
244 Self::Ada => NVML_DEVICE_ARCH_ADA,
245 Self::Hopper => NVML_DEVICE_ARCH_HOPPER,
246 Self::Blackwell => NVML_DEVICE_ARCH_BLACKWELL,
247 Self::Unknown => NVML_DEVICE_ARCH_UNKNOWN,
248 }
249 }
250}
251
252impl TryFrom<nvmlDeviceArchitecture_t> for DeviceArchitecture {
253 type Error = NvmlError;
254
255 fn try_from(data: nvmlDeviceArchitecture_t) -> Result<Self, Self::Error> {
256 match data {
257 NVML_DEVICE_ARCH_KEPLER => Ok(Self::Kepler),
258 NVML_DEVICE_ARCH_MAXWELL => Ok(Self::Maxwell),
259 NVML_DEVICE_ARCH_PASCAL => Ok(Self::Pascal),
260 NVML_DEVICE_ARCH_VOLTA => Ok(Self::Volta),
261 NVML_DEVICE_ARCH_TURING => Ok(Self::Turing),
262 NVML_DEVICE_ARCH_AMPERE => Ok(Self::Ampere),
263 NVML_DEVICE_ARCH_ADA => Ok(Self::Ada),
264 NVML_DEVICE_ARCH_HOPPER => Ok(Self::Hopper),
265 NVML_DEVICE_ARCH_BLACKWELL => Ok(Self::Blackwell),
266 NVML_DEVICE_ARCH_UNKNOWN => Ok(Self::Unknown),
267 _ => Err(NvmlError::UnexpectedVariant(data)),
268 }
269 }
270}
271
272impl Display for DeviceArchitecture {
273 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
274 match self {
275 Self::Kepler => f.write_str("Kepler"),
276 Self::Maxwell => f.write_str("Maxwell"),
277 Self::Pascal => f.write_str("Pascal"),
278 Self::Volta => f.write_str("Volta"),
279 Self::Turing => f.write_str("Turing"),
280 Self::Ampere => f.write_str("Ampere"),
281 Self::Ada => f.write_str("Ada"),
282 Self::Hopper => f.write_str("Hopper"),
283 Self::Blackwell => f.write_str("Blackwell"),
284 Self::Unknown => f.write_str("Unknown"),
285 }
286 }
287}
288
289#[derive(Debug, Clone, Eq, PartialEq, Hash)]
302#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
303pub enum PcieLinkMaxSpeed {
304 Invalid,
305 MegaTransfersPerSecond2500,
306 MegaTransfersPerSecond5000,
307 MegaTransfersPerSecond8000,
308 MegaTransfersPerSecond16000,
309 MegaTransfersPerSecond32000,
310}
311
312impl PcieLinkMaxSpeed {
313 pub fn as_integer(&self) -> Option<u32> {
315 Some(match self {
316 PcieLinkMaxSpeed::Invalid => return None,
317 PcieLinkMaxSpeed::MegaTransfersPerSecond2500 => 2500,
318 PcieLinkMaxSpeed::MegaTransfersPerSecond5000 => 5000,
319 PcieLinkMaxSpeed::MegaTransfersPerSecond8000 => 8000,
320 PcieLinkMaxSpeed::MegaTransfersPerSecond16000 => 16000,
321 PcieLinkMaxSpeed::MegaTransfersPerSecond32000 => 32000,
322 })
323 }
324
325 pub fn as_c(&self) -> c_uint {
327 match *self {
328 Self::Invalid => NVML_PCIE_LINK_MAX_SPEED_INVALID,
329 Self::MegaTransfersPerSecond2500 => NVML_PCIE_LINK_MAX_SPEED_2500MBPS,
330 Self::MegaTransfersPerSecond5000 => NVML_PCIE_LINK_MAX_SPEED_5000MBPS,
331 Self::MegaTransfersPerSecond8000 => NVML_PCIE_LINK_MAX_SPEED_8000MBPS,
332 Self::MegaTransfersPerSecond16000 => NVML_PCIE_LINK_MAX_SPEED_16000MBPS,
333 Self::MegaTransfersPerSecond32000 => NVML_PCIE_LINK_MAX_SPEED_32000MBPS,
334 }
335 }
336}
337
338impl TryFrom<c_uint> for PcieLinkMaxSpeed {
339 type Error = NvmlError;
340
341 fn try_from(data: c_uint) -> Result<Self, Self::Error> {
342 match data {
343 NVML_PCIE_LINK_MAX_SPEED_INVALID => Ok(Self::Invalid),
344 NVML_PCIE_LINK_MAX_SPEED_2500MBPS => Ok(Self::MegaTransfersPerSecond2500),
345 NVML_PCIE_LINK_MAX_SPEED_5000MBPS => Ok(Self::MegaTransfersPerSecond5000),
346 NVML_PCIE_LINK_MAX_SPEED_8000MBPS => Ok(Self::MegaTransfersPerSecond8000),
347 NVML_PCIE_LINK_MAX_SPEED_16000MBPS => Ok(Self::MegaTransfersPerSecond16000),
348 NVML_PCIE_LINK_MAX_SPEED_32000MBPS => Ok(Self::MegaTransfersPerSecond32000),
349 _ => Err(NvmlError::UnexpectedVariant(data)),
350 }
351 }
352}
353
354#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
355#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
356#[repr(u32)]
357pub enum FanControlPolicy {
358 TemperatureContinousSw = NVML_FAN_POLICY_TEMPERATURE_CONTINOUS_SW,
359 Manual = NVML_FAN_POLICY_MANUAL,
360}
361
362impl FanControlPolicy {
368 pub fn as_c(&self) -> nvmlFanControlPolicy_t {
369 *self as u32
370 }
371}
372
373impl TryFrom<nvmlFanControlPolicy_t> for FanControlPolicy {
374 type Error = NvmlError;
375
376 fn try_from(value: nvmlFanControlPolicy_t) -> Result<Self, Self::Error> {
377 match value {
378 NVML_FAN_POLICY_TEMPERATURE_CONTINOUS_SW => Ok(Self::TemperatureContinousSw),
379 NVML_FAN_POLICY_MANUAL => Ok(Self::Manual),
380 _ => Err(NvmlError::UnexpectedVariant(value)),
381 }
382 }
383}