use std::convert::TryFrom;
use std::fmt::Display;
use std::os::raw::c_uint;
use crate::enum_wrappers::device::{ClockLimitId, SampleValueType};
use crate::error::NvmlError;
use crate::ffi::bindings::*;
#[cfg(feature = "serde")]
use serde_derive::{Deserialize, Serialize};
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum FirmwareVersion {
Unavailable,
Version(u32),
}
impl From<u32> for FirmwareVersion {
fn from(value: u32) -> Self {
match value {
0 => FirmwareVersion::Unavailable,
_ => FirmwareVersion::Version(value),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum UsedGpuMemory {
Unavailable,
Used(u64),
}
impl From<u64> for UsedGpuMemory {
fn from(value: u64) -> Self {
let not_available = (NVML_VALUE_NOT_AVAILABLE) as u64;
match value {
v if v == not_available => UsedGpuMemory::Unavailable,
_ => UsedGpuMemory::Used(value),
}
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum SampleValue {
F64(f64),
U32(u32),
U64(u64),
I64(i64),
}
impl SampleValue {
pub fn from_tag_and_union(tag: &SampleValueType, union: nvmlValue_t) -> Self {
use self::SampleValueType::*;
unsafe {
match *tag {
Double => SampleValue::F64(union.dVal),
UnsignedInt => SampleValue::U32(union.uiVal),
#[allow(clippy::unnecessary_cast)]
UnsignedLong => SampleValue::U32(union.ulVal as u32),
UnsignedLongLong => SampleValue::U64(union.ullVal),
SignedLongLong => SampleValue::I64(union.sllVal),
}
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum GpuLockedClocksSetting {
Numeric {
min_clock_mhz: u32,
max_clock_mhz: u32,
},
Symbolic {
lower_bound: ClockLimitId,
upper_bound: ClockLimitId,
},
}
impl GpuLockedClocksSetting {
pub fn into_min_and_max_clocks(self) -> (u32, u32) {
match self {
GpuLockedClocksSetting::Numeric {
min_clock_mhz,
max_clock_mhz,
} => (min_clock_mhz, max_clock_mhz),
GpuLockedClocksSetting::Symbolic {
lower_bound,
upper_bound,
} => (lower_bound.as_c(), upper_bound.as_c()),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum BusType {
Unknown,
Pci,
Pcie,
Fpci,
Agp,
}
impl BusType {
pub fn as_c(&self) -> nvmlBusType_t {
match *self {
Self::Unknown => NVML_BUS_TYPE_UNKNOWN,
Self::Pci => NVML_BUS_TYPE_PCI,
Self::Pcie => NVML_BUS_TYPE_PCIE,
Self::Fpci => NVML_BUS_TYPE_FPCI,
Self::Agp => NVML_BUS_TYPE_AGP,
}
}
}
impl TryFrom<nvmlBusType_t> for BusType {
type Error = NvmlError;
fn try_from(data: nvmlBusType_t) -> Result<Self, Self::Error> {
match data {
NVML_BUS_TYPE_UNKNOWN => Ok(Self::Unknown),
NVML_BUS_TYPE_PCI => Ok(Self::Pci),
NVML_BUS_TYPE_PCIE => Ok(Self::Pcie),
NVML_BUS_TYPE_FPCI => Ok(Self::Fpci),
NVML_BUS_TYPE_AGP => Ok(Self::Agp),
_ => Err(NvmlError::UnexpectedVariant(data)),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PowerSource {
Ac,
Battery,
}
impl PowerSource {
pub fn as_c(&self) -> nvmlPowerSource_t {
match *self {
Self::Ac => NVML_POWER_SOURCE_AC,
Self::Battery => NVML_POWER_SOURCE_BATTERY,
}
}
}
impl TryFrom<nvmlPowerSource_t> for PowerSource {
type Error = NvmlError;
fn try_from(data: nvmlPowerSource_t) -> Result<Self, Self::Error> {
match data {
NVML_POWER_SOURCE_AC => Ok(Self::Ac),
NVML_POWER_SOURCE_BATTERY => Ok(Self::Battery),
_ => Err(NvmlError::UnexpectedVariant(data)),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum DeviceArchitecture {
Kepler,
Maxwell,
Pascal,
Volta,
Turing,
Ampere,
Ada,
Hopper,
Unknown,
}
impl DeviceArchitecture {
pub fn as_c(&self) -> nvmlDeviceArchitecture_t {
match *self {
Self::Kepler => NVML_DEVICE_ARCH_KEPLER,
Self::Maxwell => NVML_DEVICE_ARCH_MAXWELL,
Self::Pascal => NVML_DEVICE_ARCH_PASCAL,
Self::Volta => NVML_DEVICE_ARCH_VOLTA,
Self::Turing => NVML_DEVICE_ARCH_TURING,
Self::Ampere => NVML_DEVICE_ARCH_AMPERE,
Self::Ada => NVML_DEVICE_ARCH_ADA,
Self::Hopper => NVML_DEVICE_ARCH_HOPPER,
Self::Unknown => NVML_DEVICE_ARCH_UNKNOWN,
}
}
}
impl TryFrom<nvmlDeviceArchitecture_t> for DeviceArchitecture {
type Error = NvmlError;
fn try_from(data: nvmlDeviceArchitecture_t) -> Result<Self, Self::Error> {
match data {
NVML_DEVICE_ARCH_KEPLER => Ok(Self::Kepler),
NVML_DEVICE_ARCH_MAXWELL => Ok(Self::Maxwell),
NVML_DEVICE_ARCH_PASCAL => Ok(Self::Pascal),
NVML_DEVICE_ARCH_VOLTA => Ok(Self::Volta),
NVML_DEVICE_ARCH_TURING => Ok(Self::Turing),
NVML_DEVICE_ARCH_AMPERE => Ok(Self::Ampere),
NVML_DEVICE_ARCH_ADA => Ok(Self::Ada),
NVML_DEVICE_ARCH_HOPPER => Ok(Self::Hopper),
NVML_DEVICE_ARCH_UNKNOWN => Ok(Self::Unknown),
_ => Err(NvmlError::UnexpectedVariant(data)),
}
}
}
impl Display for DeviceArchitecture {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Kepler => f.write_str("Kepler"),
Self::Maxwell => f.write_str("Maxwell"),
Self::Pascal => f.write_str("Pascal"),
Self::Volta => f.write_str("Volta"),
Self::Turing => f.write_str("Turing"),
Self::Ampere => f.write_str("Ampere"),
Self::Ada => f.write_str("Ada"),
Self::Hopper => f.write_str("Hopper"),
Self::Unknown => f.write_str("Unknown"),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PcieLinkMaxSpeed {
Invalid,
MegaTransfersPerSecond2500,
MegaTransfersPerSecond5000,
MegaTransfersPerSecond8000,
MegaTransfersPerSecond16000,
MegaTransfersPerSecond32000,
}
impl PcieLinkMaxSpeed {
pub fn as_integer(&self) -> Option<u32> {
Some(match self {
PcieLinkMaxSpeed::Invalid => return None,
PcieLinkMaxSpeed::MegaTransfersPerSecond2500 => 2500,
PcieLinkMaxSpeed::MegaTransfersPerSecond5000 => 5000,
PcieLinkMaxSpeed::MegaTransfersPerSecond8000 => 8000,
PcieLinkMaxSpeed::MegaTransfersPerSecond16000 => 16000,
PcieLinkMaxSpeed::MegaTransfersPerSecond32000 => 32000,
})
}
pub fn as_c(&self) -> c_uint {
match *self {
Self::Invalid => NVML_PCIE_LINK_MAX_SPEED_INVALID,
Self::MegaTransfersPerSecond2500 => NVML_PCIE_LINK_MAX_SPEED_2500MBPS,
Self::MegaTransfersPerSecond5000 => NVML_PCIE_LINK_MAX_SPEED_5000MBPS,
Self::MegaTransfersPerSecond8000 => NVML_PCIE_LINK_MAX_SPEED_8000MBPS,
Self::MegaTransfersPerSecond16000 => NVML_PCIE_LINK_MAX_SPEED_16000MBPS,
Self::MegaTransfersPerSecond32000 => NVML_PCIE_LINK_MAX_SPEED_32000MBPS,
}
}
}
impl TryFrom<c_uint> for PcieLinkMaxSpeed {
type Error = NvmlError;
fn try_from(data: c_uint) -> Result<Self, Self::Error> {
match data {
NVML_PCIE_LINK_MAX_SPEED_INVALID => Ok(Self::Invalid),
NVML_PCIE_LINK_MAX_SPEED_2500MBPS => Ok(Self::MegaTransfersPerSecond2500),
NVML_PCIE_LINK_MAX_SPEED_5000MBPS => Ok(Self::MegaTransfersPerSecond5000),
NVML_PCIE_LINK_MAX_SPEED_8000MBPS => Ok(Self::MegaTransfersPerSecond8000),
NVML_PCIE_LINK_MAX_SPEED_16000MBPS => Ok(Self::MegaTransfersPerSecond16000),
NVML_PCIE_LINK_MAX_SPEED_32000MBPS => Ok(Self::MegaTransfersPerSecond32000),
_ => Err(NvmlError::UnexpectedVariant(data)),
}
}
}