Skip to content

Commit 04af00c

Browse files
Add fan control functions (#77)
Adds several fan control functions from NVML.
1 parent 9abfe55 commit 04af00c

File tree

3 files changed

+125
-35
lines changed

3 files changed

+125
-35
lines changed

nvml-wrapper/src/device.rs

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ use crate::bitmasks::Behavior;
1111

1212
use crate::enum_wrappers::{bool_from_state, device::*, state_from_bool};
1313

14-
use crate::enums::device::BusType;
15-
use crate::enums::device::DeviceArchitecture;
16-
use crate::enums::device::GpuLockedClocksSetting;
17-
use crate::enums::device::PcieLinkMaxSpeed;
18-
use crate::enums::device::PowerSource;
14+
use crate::enums::device::{
15+
BusType, DeviceArchitecture, FanControlPolicy, GpuLockedClocksSetting, PcieLinkMaxSpeed,
16+
PowerSource,
17+
};
1918
#[cfg(target_os = "linux")]
2019
use crate::error::NvmlErrorWithSource;
2120
use crate::error::{nvml_sym, nvml_try, Bits, NvmlError};
@@ -1541,6 +1540,89 @@ impl<'nvml> Device<'nvml> {
15411540
}
15421541
}
15431542

1543+
/**
1544+
Gets current fan control policy.
1545+
1546+
You can determine valid fan indices using [`Self::num_fans()`].
1547+
1548+
# Errors
1549+
1550+
* `Uninitialized`, if the library has not been successfully initialized
1551+
* `InvalidArg`, if this `Device` is invalid or `fan_idx` is invalid
1552+
* `NotSupported`, if this `Device` does not have a fan
1553+
* `GpuLost`, if this `Device` has fallen off the bus or is otherwise inaccessible
1554+
* `UnexpectedVariant`, for which you can read the docs for
1555+
* `Unknown`, on any unexpected error
1556+
1557+
# Device Support
1558+
1559+
Supports Maxwell or newer fully supported discrete devices with fans.
1560+
*/
1561+
#[doc(alias = "nvmlGetFanControlPolicy_v2")]
1562+
pub fn fan_control_policy(&self, fan_idx: u32) -> Result<FanControlPolicy, NvmlError> {
1563+
let sym = nvml_sym(self.nvml.lib.nvmlDeviceGetFanControlPolicy_v2.as_ref())?;
1564+
1565+
unsafe {
1566+
let mut policy: nvmlFanControlPolicy_t = mem::zeroed();
1567+
nvml_try(sym(self.device, fan_idx, &mut policy))?;
1568+
1569+
FanControlPolicy::try_from(policy)
1570+
}
1571+
}
1572+
1573+
/**
1574+
Sets the speed of a specified fan.
1575+
1576+
WARNING: This function changes the fan control policy to manual. It means that YOU have to monitor the temperature and adjust the fan speed accordingly.
1577+
If you set the fan speed too low you can burn your GPU! Use [`Device::set_default_fan_speed`] to restore default control policy.
1578+
1579+
You can determine valid fan indices using [`Self::num_fans()`].
1580+
1581+
# Errors
1582+
1583+
* `Uninitialized`, if the library has not been successfully initialized
1584+
* `InvalidArg`, if this `Device` is invalid or `fan_idx` is invalid
1585+
* `NotSupported`, if this `Device` does not have a fan
1586+
* `GpuLost`, if this `Device` has fallen off the bus or is otherwise inaccessible
1587+
* `UnexpectedVariant`, for which you can read the docs for
1588+
* `Unknown`, on any unexpected error
1589+
1590+
# Device Support
1591+
1592+
Supports Maxwell or newer fully supported discrete devices with fans.
1593+
*/
1594+
#[doc(alias = "nvmlDeviceSetFanSpeed_v2")]
1595+
pub fn set_fan_speed(&mut self, fan_idx: u32, speed: u32) -> Result<(), NvmlError> {
1596+
let sym = nvml_sym(self.nvml.lib.nvmlDeviceSetFanSpeed_v2.as_ref())?;
1597+
1598+
unsafe { nvml_try(sym(self.device, fan_idx, speed)) }
1599+
}
1600+
1601+
/**
1602+
Sets the the fan control policy to default.
1603+
1604+
You can determine valid fan indices using [`Self::num_fans()`].
1605+
1606+
# Errors
1607+
1608+
* `Uninitialized`, if the library has not been successfully initialized
1609+
* `InvalidArg`, if this `Device` is invalid or `fan_idx` is invalid
1610+
* `NotSupported`, if this `Device` does not have a fan
1611+
* `GpuLost`, if this `Device` has fallen off the bus or is otherwise inaccessible
1612+
* `UnexpectedVariant`, for which you can read the docs for
1613+
* `Unknown`, on any unexpected error
1614+
1615+
# Device Support
1616+
1617+
Supports Maxwell or newer fully supported discrete devices with fans.
1618+
*/
1619+
#[doc(alias = "nvmlDeviceSetDefaultFanSpeed_v2")]
1620+
pub fn set_default_fan_speed(&mut self, fan_idx: u32) -> Result<(), NvmlError> {
1621+
let sym = nvml_sym(self.nvml.lib.nvmlDeviceSetDefaultFanSpeed_v2.as_ref())?;
1622+
1623+
unsafe { nvml_try(sym(self.device, fan_idx)) }
1624+
}
1625+
15441626
/**
15451627
Gets the number of fans on this [`Device`].
15461628

nvml-wrapper/src/enums/device.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,3 +350,34 @@ impl TryFrom<c_uint> for PcieLinkMaxSpeed {
350350
}
351351
}
352352
}
353+
354+
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
355+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
356+
#[repr(u32)]
357+
pub enum FanControlPolicy {
358+
TemperatureContinousSw = NVML_FAN_POLICY_TEMPERATURE_CONTINOUS_SW,
359+
Manual = NVML_FAN_POLICY_MANUAL,
360+
}
361+
362+
/// Returned by [`crate::Device::get_fan_control_policy()`].
363+
///
364+
/// Policy used for fan control.
365+
// TODO: technically this is an "enum wrapper" but the type on the C side isn't
366+
// an enum
367+
impl FanControlPolicy {
368+
pub fn as_c(&self) -> nvmlFanControlPolicy_t {
369+
*self as u32
370+
}
371+
}
372+
373+
impl 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::TemperatureContinousSw),
380+
_ => Err(NvmlError::UnexpectedVariant(value)),
381+
}
382+
}
383+
}

nvml-wrapper/unwrapped_functions.txt

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,22 @@ nvmlComputeInstanceGetInfo_v2
55
nvmlDeviceClearFieldValues
66
nvmlDeviceCreateGpuInstance
77
nvmlDeviceCreateGpuInstanceWithPlacement
8-
nvmlDeviceFreezeNvLinkUtilizationCounter
98
nvmlDeviceGetActiveVgpus
109
nvmlDeviceGetAdaptiveClockInfoStatus
1110
nvmlDeviceGetAttributes
1211
nvmlDeviceGetAttributes_v2
1312
nvmlDeviceGetClkMonStatus
1413
nvmlDeviceGetComputeInstanceId
15-
nvmlDeviceGetComputeRunningProcesses
16-
nvmlDeviceGetComputeRunningProcesses_v2
17-
nvmlDeviceGetComputeRunningProcesses_v3
1814
nvmlDeviceGetConfComputeGpuAttestationReport
1915
nvmlDeviceGetConfComputeGpuCertificate
2016
nvmlDeviceGetConfComputeMemSizeInfo
2117
nvmlDeviceGetConfComputeProtectedMemoryUsage
2218
nvmlDeviceGetCpuAffinityWithinScope
2319
nvmlDeviceGetCreatableVgpus
2420
nvmlDeviceGetCurrentClocksEventReasons
25-
nvmlDeviceGetCurrentClocksThrottleReasons
2621
nvmlDeviceGetDefaultEccMode
2722
nvmlDeviceGetDeviceHandleFromMigDeviceHandle
2823
nvmlDeviceGetDynamicPstatesInfo
29-
nvmlDeviceGetFanControlPolicy_v2
3024
nvmlDeviceGetGpcClkMinMaxVfOffset
3125
nvmlDeviceGetGpcClkVfOffset
3226
nvmlDeviceGetGpuFabricInfo
@@ -39,21 +33,14 @@ nvmlDeviceGetGpuInstanceProfileInfoV
3933
nvmlDeviceGetGpuInstanceRemainingCapacity
4034
nvmlDeviceGetGpuInstances
4135
nvmlDeviceGetGpuMaxPcieLinkGeneration
42-
nvmlDeviceGetGraphicsRunningProcesses
43-
nvmlDeviceGetGraphicsRunningProcesses_v2
44-
nvmlDeviceGetGraphicsRunningProcesses_v3
4536
nvmlDeviceGetGridLicensableFeatures
4637
nvmlDeviceGetGridLicensableFeatures_v2
4738
nvmlDeviceGetGridLicensableFeatures_v3
4839
nvmlDeviceGetGridLicensableFeatures_v4
4940
nvmlDeviceGetGspFirmwareMode
5041
nvmlDeviceGetGspFirmwareVersion
5142
nvmlDeviceGetHostVgpuMode
52-
nvmlDeviceGetInforomConfigurationChecksum
5343
nvmlDeviceGetJpgUtilization
54-
nvmlDeviceGetMPSComputeRunningProcesses
55-
nvmlDeviceGetMPSComputeRunningProcesses_v2
56-
nvmlDeviceGetMPSComputeRunningProcesses_v3
5744
nvmlDeviceGetMaxMigDeviceCount
5845
nvmlDeviceGetMemClkMinMaxVfOffset
5946
nvmlDeviceGetMemClkVfOffset
@@ -63,23 +50,16 @@ nvmlDeviceGetMigMode
6350
nvmlDeviceGetMinMaxClockOfPState
6451
nvmlDeviceGetMinMaxFanSpeed
6552
nvmlDeviceGetModuleId
66-
nvmlDeviceGetNvLinkCapability
67-
nvmlDeviceGetNvLinkErrorCounter
53+
nvmlDeviceGetMPSComputeRunningProcesses
54+
nvmlDeviceGetMPSComputeRunningProcesses_v2
55+
nvmlDeviceGetMPSComputeRunningProcesses_v3
6856
nvmlDeviceGetNvLinkRemoteDeviceType
69-
nvmlDeviceGetNvLinkRemotePciInfo
70-
nvmlDeviceGetNvLinkRemotePciInfo_v2
71-
nvmlDeviceGetNvLinkUtilizationControl
72-
nvmlDeviceGetNvLinkUtilizationCounter
7357
nvmlDeviceGetOfaUtilization
7458
nvmlDeviceGetPgpuMetadataString
75-
nvmlDeviceGetPowerManagementDefaultLimit
76-
nvmlDeviceGetPowerManagementLimitConstraints
7759
nvmlDeviceGetRemappedRows
78-
nvmlDeviceGetRetiredPagesPendingStatus
7960
nvmlDeviceGetRowRemapperHistogram
8061
nvmlDeviceGetRunningProcessDetailList
8162
nvmlDeviceGetSupportedClocksEventReasons
82-
nvmlDeviceGetSupportedClocksThrottleReasons
8363
nvmlDeviceGetSupportedPerformanceStates
8464
nvmlDeviceGetSupportedVgpus
8565
nvmlDeviceGetTargetFanSpeed
@@ -93,18 +73,12 @@ nvmlDeviceGetVgpuSchedulerState
9373
nvmlDeviceGetVgpuUtilization
9474
nvmlDeviceGetVirtualizationMode
9575
nvmlDeviceIsMigDeviceHandle
96-
nvmlDeviceResetNvLinkErrorCounters
97-
nvmlDeviceResetNvLinkUtilizationCounter
9876
nvmlDeviceSetConfComputeUnprotectedMemSize
99-
nvmlDeviceSetDefaultAutoBoostedClocksEnabled
100-
nvmlDeviceSetDefaultFanSpeed_v2
10177
nvmlDeviceSetFanControlPolicy
102-
nvmlDeviceSetFanSpeed_v2
10378
nvmlDeviceSetGpcClkVfOffset
10479
nvmlDeviceSetMemClkVfOffset
10580
nvmlDeviceSetMigMode
10681
nvmlDeviceSetNvLinkDeviceLowPowerThreshold
107-
nvmlDeviceSetNvLinkUtilizationControl
10882
nvmlDeviceSetTemperatureThreshold
10983
nvmlDeviceSetVgpuSchedulerState
11084
nvmlDeviceSetVirtualizationMode
@@ -164,8 +138,8 @@ nvmlVgpuInstanceSetEncoderCapacity
164138
nvmlVgpuTypeGetCapabilities
165139
nvmlVgpuTypeGetClass
166140
nvmlVgpuTypeGetDeviceID
167-
nvmlVgpuTypeGetFrameRateLimit
168141
nvmlVgpuTypeGetFramebufferSize
142+
nvmlVgpuTypeGetFrameRateLimit
169143
nvmlVgpuTypeGetGpuInstanceProfileId
170144
nvmlVgpuTypeGetLicense
171145
nvmlVgpuTypeGetMaxInstances
@@ -181,11 +155,14 @@ this means some version is already wrapped and the listed names are either
181155
newer versions to be wrapped or older versions that could be wrapped behind the
182156
legacy-functions feature.
183157

158+
nvmlDeviceGetComputeRunningProcesses
184159
nvmlDeviceGetCount
185160
nvmlDeviceGetFanSpeed
161+
nvmlDeviceGetGraphicsRunningProcesses
186162
nvmlDeviceGetHandleByIndex
187163
nvmlDeviceGetHandleByPciBusId
188164
nvmlDeviceGetMemoryInfo_v2
165+
nvmlDeviceGetNvLinkRemotePciInfo
189166
nvmlDeviceGetPciInfo
190167
nvmlDeviceGetPciInfo_v2
191168
nvmlDeviceRemoveGpu

0 commit comments

Comments
 (0)