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 Unknown,
230}
231
232impl DeviceArchitecture {
233 pub fn as_c(&self) -> nvmlDeviceArchitecture_t {
235 match *self {
236 Self::Kepler => NVML_DEVICE_ARCH_KEPLER,
237 Self::Maxwell => NVML_DEVICE_ARCH_MAXWELL,
238 Self::Pascal => NVML_DEVICE_ARCH_PASCAL,
239 Self::Volta => NVML_DEVICE_ARCH_VOLTA,
240 Self::Turing => NVML_DEVICE_ARCH_TURING,
241 Self::Ampere => NVML_DEVICE_ARCH_AMPERE,
242 Self::Ada => NVML_DEVICE_ARCH_ADA,
243 Self::Hopper => NVML_DEVICE_ARCH_HOPPER,
244 Self::Unknown => NVML_DEVICE_ARCH_UNKNOWN,
245 }
246 }
247}
248
249impl TryFrom<nvmlDeviceArchitecture_t> for DeviceArchitecture {
250 type Error = NvmlError;
251
252 fn try_from(data: nvmlDeviceArchitecture_t) -> Result<Self, Self::Error> {
253 match data {
254 NVML_DEVICE_ARCH_KEPLER => Ok(Self::Kepler),
255 NVML_DEVICE_ARCH_MAXWELL => Ok(Self::Maxwell),
256 NVML_DEVICE_ARCH_PASCAL => Ok(Self::Pascal),
257 NVML_DEVICE_ARCH_VOLTA => Ok(Self::Volta),
258 NVML_DEVICE_ARCH_TURING => Ok(Self::Turing),
259 NVML_DEVICE_ARCH_AMPERE => Ok(Self::Ampere),
260 NVML_DEVICE_ARCH_ADA => Ok(Self::Ada),
261 NVML_DEVICE_ARCH_HOPPER => Ok(Self::Hopper),
262 NVML_DEVICE_ARCH_UNKNOWN => Ok(Self::Unknown),
263 _ => Err(NvmlError::UnexpectedVariant(data)),
264 }
265 }
266}
267
268impl Display for DeviceArchitecture {
269 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
270 match self {
271 Self::Kepler => f.write_str("Kepler"),
272 Self::Maxwell => f.write_str("Maxwell"),
273 Self::Pascal => f.write_str("Pascal"),
274 Self::Volta => f.write_str("Volta"),
275 Self::Turing => f.write_str("Turing"),
276 Self::Ampere => f.write_str("Ampere"),
277 Self::Ada => f.write_str("Ada"),
278 Self::Hopper => f.write_str("Hopper"),
279 Self::Unknown => f.write_str("Unknown"),
280 }
281 }
282}
283
284#[derive(Debug, Clone, Eq, PartialEq, Hash)]
297#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
298pub enum PcieLinkMaxSpeed {
299 Invalid,
300 MegaTransfersPerSecond2500,
301 MegaTransfersPerSecond5000,
302 MegaTransfersPerSecond8000,
303 MegaTransfersPerSecond16000,
304 MegaTransfersPerSecond32000,
305}
306
307impl PcieLinkMaxSpeed {
308 pub fn as_integer(&self) -> Option<u32> {
310 Some(match self {
311 PcieLinkMaxSpeed::Invalid => return None,
312 PcieLinkMaxSpeed::MegaTransfersPerSecond2500 => 2500,
313 PcieLinkMaxSpeed::MegaTransfersPerSecond5000 => 5000,
314 PcieLinkMaxSpeed::MegaTransfersPerSecond8000 => 8000,
315 PcieLinkMaxSpeed::MegaTransfersPerSecond16000 => 16000,
316 PcieLinkMaxSpeed::MegaTransfersPerSecond32000 => 32000,
317 })
318 }
319
320 pub fn as_c(&self) -> c_uint {
322 match *self {
323 Self::Invalid => NVML_PCIE_LINK_MAX_SPEED_INVALID,
324 Self::MegaTransfersPerSecond2500 => NVML_PCIE_LINK_MAX_SPEED_2500MBPS,
325 Self::MegaTransfersPerSecond5000 => NVML_PCIE_LINK_MAX_SPEED_5000MBPS,
326 Self::MegaTransfersPerSecond8000 => NVML_PCIE_LINK_MAX_SPEED_8000MBPS,
327 Self::MegaTransfersPerSecond16000 => NVML_PCIE_LINK_MAX_SPEED_16000MBPS,
328 Self::MegaTransfersPerSecond32000 => NVML_PCIE_LINK_MAX_SPEED_32000MBPS,
329 }
330 }
331}
332
333impl TryFrom<c_uint> for PcieLinkMaxSpeed {
334 type Error = NvmlError;
335
336 fn try_from(data: c_uint) -> Result<Self, Self::Error> {
337 match data {
338 NVML_PCIE_LINK_MAX_SPEED_INVALID => Ok(Self::Invalid),
339 NVML_PCIE_LINK_MAX_SPEED_2500MBPS => Ok(Self::MegaTransfersPerSecond2500),
340 NVML_PCIE_LINK_MAX_SPEED_5000MBPS => Ok(Self::MegaTransfersPerSecond5000),
341 NVML_PCIE_LINK_MAX_SPEED_8000MBPS => Ok(Self::MegaTransfersPerSecond8000),
342 NVML_PCIE_LINK_MAX_SPEED_16000MBPS => Ok(Self::MegaTransfersPerSecond16000),
343 NVML_PCIE_LINK_MAX_SPEED_32000MBPS => Ok(Self::MegaTransfersPerSecond32000),
344 _ => Err(NvmlError::UnexpectedVariant(data)),
345 }
346 }
347}