@@ -1840,6 +1840,36 @@ impl<'nvml> Device<'nvml> {
1840
1840
}
1841
1841
}
1842
1842
1843
+ /**
1844
+ Retrieves the min and max fan speed that user can set for the GPU fan.
1845
+
1846
+ Returns a (min, max) tuple.
1847
+
1848
+ # Errors
1849
+
1850
+ * `Uninitialized`, if the library has not been successfully initialized
1851
+ * `InvalidArg`, if this `Device` is invalid
1852
+ * `NotSupported`, if this `Device` does not have fans
1853
+ * `Unknown`, on any unexpected error
1854
+
1855
+ # Device Support
1856
+
1857
+ For all cuda-capable discrete products with fans
1858
+ */
1859
+ // Checked against local
1860
+ // Tested
1861
+ #[ doc( alias = "nvmlDeviceGetMinMaxFanSpeed" ) ]
1862
+ pub fn min_max_fan_speed ( & self ) -> Result < ( u32 , u32 ) , NvmlError > {
1863
+ let sym = nvml_sym ( self . nvml . lib . nvmlDeviceGetMinMaxFanSpeed . as_ref ( ) ) ?;
1864
+
1865
+ unsafe {
1866
+ let mut min = mem:: zeroed ( ) ;
1867
+ let mut max = mem:: zeroed ( ) ;
1868
+ nvml_try ( sym ( self . device , & mut min, & mut max) ) ?;
1869
+ Ok ( ( min, max) )
1870
+ }
1871
+ }
1872
+
1843
1873
/**
1844
1874
Gets current fan control policy.
1845
1875
@@ -5210,6 +5240,167 @@ impl<'nvml> Device<'nvml> {
5210
5240
unsafe { nvml_try ( sym ( self . device , limit) ) }
5211
5241
}
5212
5242
5243
+ /**
5244
+ Retrieve min, max and current clock offset of some clock domain for a given PState
5245
+
5246
+ # Errors
5247
+
5248
+ * `Uninitialized`, if the library has not been successfully initialized
5249
+ * `InvalidArg`, If device, type or pstate are invalid or both minClockOffsetMHz and maxClockOffsetMHz are NULL
5250
+ * `ArgumentVersionMismatch`, if the provided version is invalid/unsupported
5251
+ * `NotSupported`, if this `Device` does not support this feature
5252
+
5253
+ # Device Support
5254
+
5255
+ Supports Maxwell and newer fully supported devices.
5256
+ */
5257
+ // Checked against local
5258
+ // Tested
5259
+ #[ doc( alias = "nvmlDeviceGetClockOffsets" ) ]
5260
+ pub fn clock_offset (
5261
+ & self ,
5262
+ clock_type : Clock ,
5263
+ power_state : PerformanceState ,
5264
+ ) -> Result < ClockOffset , NvmlError > {
5265
+ let sym = nvml_sym ( self . nvml . lib . nvmlDeviceGetClockOffsets . as_ref ( ) ) ?;
5266
+
5267
+ unsafe {
5268
+ // Implements NVML_STRUCT_VERSION(ClockOffset, 1), as detailed in nvml.h
5269
+ let version =
5270
+ ( std:: mem:: size_of :: < nvmlClockOffset_v1_t > ( ) | ( 1_usize << 24_usize ) ) as u32 ;
5271
+
5272
+ let mut clock_offset = nvmlClockOffset_v1_t {
5273
+ version,
5274
+ type_ : clock_type. as_c ( ) ,
5275
+ pstate : power_state. as_c ( ) ,
5276
+ clockOffsetMHz : mem:: zeroed ( ) ,
5277
+ minClockOffsetMHz : mem:: zeroed ( ) ,
5278
+ maxClockOffsetMHz : mem:: zeroed ( ) ,
5279
+ } ;
5280
+ nvml_try ( sym ( self . device , & mut clock_offset) ) ?;
5281
+ ClockOffset :: try_from ( clock_offset)
5282
+ }
5283
+ }
5284
+
5285
+ /**
5286
+ Control current clock offset of some clock domain for a given PState
5287
+
5288
+ # Errors
5289
+
5290
+ * `Uninitialized`, if the library has not been successfully initialized
5291
+ * `NoPermission`, if the user doesn't have permission to perform this operation
5292
+ * `InvalidArg`, If device, type or pstate are invalid or both clockOffsetMHz is out of allowed range
5293
+ * `ArgumentVersionMismatch`, if the provided version is invalid/unsupported
5294
+
5295
+ # Device Support
5296
+
5297
+ Supports Maxwell and newer fully supported devices.
5298
+ */
5299
+ // Checked against local
5300
+ // Tested (no-run)
5301
+ #[ doc( alias = "nvmlDeviceSetClockOffsets" ) ]
5302
+ pub fn set_clock_offset (
5303
+ & mut self ,
5304
+ clock_type : Clock ,
5305
+ power_state : PerformanceState ,
5306
+ offset : i32 ,
5307
+ ) -> Result < ( ) , NvmlError > {
5308
+ let sym = nvml_sym ( self . nvml . lib . nvmlDeviceSetClockOffsets . as_ref ( ) ) ?;
5309
+
5310
+ unsafe {
5311
+ // Implements NVML_STRUCT_VERSION(ClockOffset, 1), as detailed in nvml.h
5312
+ let version =
5313
+ ( std:: mem:: size_of :: < nvmlClockOffset_v1_t > ( ) | ( 1_usize << 24_usize ) ) as u32 ;
5314
+
5315
+ let mut clock_offset = nvmlClockOffset_v1_t {
5316
+ version,
5317
+ type_ : clock_type. as_c ( ) ,
5318
+ pstate : power_state. as_c ( ) ,
5319
+ clockOffsetMHz : offset,
5320
+ minClockOffsetMHz : 0 ,
5321
+ maxClockOffsetMHz : 0 ,
5322
+ } ;
5323
+ nvml_try ( sym ( self . device , & mut clock_offset) ) ?;
5324
+ Ok ( ( ) )
5325
+ }
5326
+ }
5327
+
5328
+ /**
5329
+ Get all supported Performance States (P-States) for the device.
5330
+ The number of elements in the returned list will never exceed [`NVML_MAX_GPU_PERF_PSTATES`]`.
5331
+
5332
+ # Errors
5333
+
5334
+ * `InsufficientSize`, if the the container supplied was not large enough to hold the resulting list
5335
+ * `Uninitialized`, if the library has not been successfully initialized
5336
+ * `InvalidArg`, if device or pstates is invalid
5337
+ * `NotSupported`, if the device does not support performance state readings
5338
+ * `Unknown`, on any unexpected error
5339
+ */
5340
+ // Checked against local
5341
+ // Tested
5342
+ #[ doc( alias = "nvmlDeviceGetSupportedPerformanceStates" ) ]
5343
+ pub fn supported_performance_states ( & self ) -> Result < Vec < PerformanceState > , NvmlError > {
5344
+ let sym = nvml_sym (
5345
+ self . nvml
5346
+ . lib
5347
+ . nvmlDeviceGetSupportedPerformanceStates
5348
+ . as_ref ( ) ,
5349
+ ) ?;
5350
+
5351
+ unsafe {
5352
+ let mut pstates =
5353
+ [ PerformanceState :: Unknown . as_c ( ) ; NVML_MAX_GPU_PERF_PSTATES as usize ] ;
5354
+ // The array size passed to `nvmlDeviceGetSupportedPerformanceStates` must be in bytes, not array length
5355
+ let byte_size = mem:: size_of_val ( & pstates) ;
5356
+
5357
+ nvml_try ( sym ( self . device , pstates. as_mut_ptr ( ) , byte_size as u32 ) ) ?;
5358
+
5359
+ pstates
5360
+ . into_iter ( )
5361
+ . take_while ( |pstate| * pstate != PerformanceState :: Unknown . as_c ( ) )
5362
+ . map ( PerformanceState :: try_from)
5363
+ . collect ( )
5364
+ }
5365
+ }
5366
+
5367
+ /**
5368
+ Retrieve min and max clocks of some clock domain for a given PState.
5369
+
5370
+ Returns a (min, max) tuple.
5371
+
5372
+ # Errors
5373
+
5374
+ * `Uninitialized`, if the library has not been successfully initialized
5375
+ * `InvalidArg`, if device, type or pstate are invalid or both minClockMHz and maxClockMHz are NULL
5376
+ * `NotSupported`, if the device does not support this feature
5377
+ */
5378
+ // Checked against local
5379
+ // Tested
5380
+ #[ doc( alias = "nvmlDeviceGetMinMaxClockOfPState" ) ]
5381
+ pub fn min_max_clock_of_pstate (
5382
+ & self ,
5383
+ clock_type : Clock ,
5384
+ pstate : PerformanceState ,
5385
+ ) -> Result < ( u32 , u32 ) , NvmlError > {
5386
+ let sym = nvml_sym ( self . nvml . lib . nvmlDeviceGetMinMaxClockOfPState . as_ref ( ) ) ?;
5387
+
5388
+ unsafe {
5389
+ let mut min: u32 = mem:: zeroed ( ) ;
5390
+ let mut max: u32 = mem:: zeroed ( ) ;
5391
+
5392
+ nvml_try ( sym (
5393
+ self . device ,
5394
+ clock_type. as_c ( ) ,
5395
+ pstate. as_c ( ) ,
5396
+ & mut min,
5397
+ & mut max,
5398
+ ) ) ?;
5399
+
5400
+ Ok ( ( min, max) )
5401
+ }
5402
+ }
5403
+
5213
5404
// Event handling methods
5214
5405
5215
5406
/**
@@ -6017,6 +6208,12 @@ mod test {
6017
6208
test_with_device ( 3 , & nvml, |device| device. fan_speed_rpm ( 0 ) )
6018
6209
}
6019
6210
6211
+ #[ test]
6212
+ fn min_max_fan_speed ( ) {
6213
+ let nvml = nvml ( ) ;
6214
+ test_with_device ( 3 , & nvml, |device| device. min_max_fan_speed ( ) )
6215
+ }
6216
+
6020
6217
#[ test]
6021
6218
fn num_fans ( ) {
6022
6219
let nvml = nvml ( ) ;
@@ -6198,6 +6395,28 @@ mod test {
6198
6395
test_with_device ( 3 , & nvml, |device| device. power_management_limit ( ) )
6199
6396
}
6200
6397
6398
+ #[ test]
6399
+ fn clock_offset ( ) {
6400
+ let nvml = nvml ( ) ;
6401
+ test_with_device ( 3 , & nvml, |device| {
6402
+ device. clock_offset ( Clock :: Graphics , PerformanceState :: Zero )
6403
+ } ) ;
6404
+ }
6405
+
6406
+ #[ test]
6407
+ fn supported_performance_states ( ) {
6408
+ let nvml = nvml ( ) ;
6409
+ test_with_device ( 3 , & nvml, |device| device. supported_performance_states ( ) ) ;
6410
+ }
6411
+
6412
+ #[ test]
6413
+ fn min_max_clock_of_pstate ( ) {
6414
+ let nvml = nvml ( ) ;
6415
+ test_with_device ( 3 , & nvml, |device| {
6416
+ device. min_max_clock_of_pstate ( Clock :: Graphics , PerformanceState :: Zero )
6417
+ } ) ;
6418
+ }
6419
+
6201
6420
#[ test]
6202
6421
fn power_management_limit_constraints ( ) {
6203
6422
let nvml = nvml ( ) ;
@@ -6737,6 +6956,17 @@ mod test {
6737
6956
. expect ( "set to true" )
6738
6957
}
6739
6958
6959
+ // This modifies device state, so we don't want to actually run the test
6960
+ #[ allow( dead_code) ]
6961
+ fn set_clock_offset ( ) {
6962
+ let nvml = nvml ( ) ;
6963
+ let mut device = device ( & nvml) ;
6964
+
6965
+ device
6966
+ . set_clock_offset ( Clock :: Graphics , PerformanceState :: Zero , -100 )
6967
+ . expect ( "set to true" )
6968
+ }
6969
+
6740
6970
#[ cfg( target_os = "linux" ) ]
6741
6971
#[ allow( unused_variables) ]
6742
6972
#[ test]
0 commit comments