1use crate::bitmasks::device::FbcFlags;
2use crate::enum_wrappers::device::{
3 BridgeChip, Clock, EncoderType, FbcSessionType, PerformanceState, SampleValueType,
4};
5use crate::enums::device::{FirmwareVersion, SampleValue, UsedGpuMemory};
6use crate::error::{nvml_try, Bits, NvmlError};
7use crate::ffi::bindings::*;
8use crate::structs::device::FieldId;
9#[cfg(feature = "serde")]
10use serde_derive::{Deserialize, Serialize};
11use std::{
12 cmp::Ordering,
13 ffi::{CStr, CString},
14};
15use std::{
16 convert::{TryFrom, TryInto},
17 os::raw::c_char,
18};
19
20#[derive(Debug, Clone, Eq, PartialEq, Hash)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25pub struct PciInfo {
26 pub bus: u32,
28 pub bus_id: String,
30 pub device: u32,
32 pub domain: u32,
34 pub pci_device_id: u32,
36 pub pci_sub_system_id: Option<u32>,
46}
47
48impl PciInfo {
49 pub fn try_from(struct_: nvmlPciInfo_t, sub_sys_id_present: bool) -> Result<Self, NvmlError> {
60 unsafe {
61 let bus_id_raw = CStr::from_ptr(struct_.busId.as_ptr());
62
63 Ok(Self {
64 bus: struct_.bus,
65 bus_id: bus_id_raw.to_str()?.into(),
66 device: struct_.device,
67 domain: struct_.domain,
68 pci_device_id: struct_.pciDeviceId,
69 pci_sub_system_id: if sub_sys_id_present {
70 Some(struct_.pciSubSystemId)
71 } else {
72 None
73 },
74 })
75 }
76 }
77}
78
79impl TryInto<nvmlPciInfo_t> for PciInfo {
80 type Error = NvmlError;
81
82 fn try_into(self) -> Result<nvmlPciInfo_t, Self::Error> {
94 const fn buf_size() -> usize {
96 NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE as usize
97 }
98
99 let mut bus_id_c: [c_char; buf_size()] = [0; buf_size()];
100 let mut bus_id = CString::new(self.bus_id)?.into_bytes_with_nul();
101
102 match bus_id.len().cmp(&buf_size()) {
104 Ordering::Less => {
105 while bus_id.len() != buf_size() {
106 bus_id.push(0);
107 }
108 }
109 Ordering::Equal => {
110 }
112 Ordering::Greater => {
113 return Err(NvmlError::StringTooLong {
114 max_len: buf_size(),
115 actual_len: bus_id.len(),
116 })
117 }
118 }
119
120 bus_id_c.clone_from_slice(&bus_id.into_iter().map(|b| b as c_char).collect::<Vec<_>>());
121
122 Ok(nvmlPciInfo_t {
123 busIdLegacy: [0; NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE as usize],
124 domain: self.domain,
125 bus: self.bus,
126 device: self.device,
127 pciDeviceId: self.pci_device_id,
128 pciSubSystemId: self.pci_sub_system_id.unwrap_or(0),
131 busId: bus_id_c,
132 })
133 }
134}
135
136#[derive(Debug, Clone, Eq, PartialEq, Hash)]
139#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
140pub struct BAR1MemoryInfo {
141 pub free: u64,
143 pub total: u64,
145 pub used: u64,
147}
148
149impl From<nvmlBAR1Memory_t> for BAR1MemoryInfo {
150 fn from(struct_: nvmlBAR1Memory_t) -> Self {
151 Self {
152 free: struct_.bar1Free,
153 total: struct_.bar1Total,
154 used: struct_.bar1Used,
155 }
156 }
157}
158
159#[derive(Debug, Clone, Eq, PartialEq, Hash)]
162#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
163pub struct BridgeChipInfo {
164 pub fw_version: FirmwareVersion,
165 pub chip_type: BridgeChip,
166}
167
168impl TryFrom<nvmlBridgeChipInfo_t> for BridgeChipInfo {
169 type Error = NvmlError;
170
171 fn try_from(value: nvmlBridgeChipInfo_t) -> Result<Self, Self::Error> {
179 let fw_version = FirmwareVersion::from(value.fwVersion);
180 let chip_type = BridgeChip::try_from(value.type_)?;
181
182 Ok(Self {
183 fw_version,
184 chip_type,
185 })
186 }
187}
188
189#[derive(Debug, Clone, Eq, PartialEq, Hash)]
197#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
198pub struct BridgeChipHierarchy {
199 pub chips_hierarchy: Vec<BridgeChipInfo>,
201 pub chip_count: u8,
203}
204
205impl TryFrom<nvmlBridgeChipHierarchy_t> for BridgeChipHierarchy {
206 type Error = NvmlError;
207
208 fn try_from(value: nvmlBridgeChipHierarchy_t) -> Result<Self, Self::Error> {
216 let chips_hierarchy = value
217 .bridgeChipInfo
218 .iter()
219 .map(|bci| BridgeChipInfo::try_from(*bci))
220 .collect::<Result<_, NvmlError>>()?;
221
222 Ok(Self {
223 chips_hierarchy,
224 chip_count: value.bridgeCount,
225 })
226 }
227}
228
229#[derive(Debug, Clone, Eq, PartialEq, Hash)]
232#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
233pub struct ProcessInfo {
234 pub pid: u32,
236 pub used_gpu_memory: UsedGpuMemory,
238 pub gpu_instance_id: Option<u32>,
243 pub compute_instance_id: Option<u32>,
248}
249
250impl From<nvmlProcessInfo_t> for ProcessInfo {
251 fn from(struct_: nvmlProcessInfo_t) -> Self {
252 const NO_VALUE: u32 = 0xFFFFFFFF;
253
254 let gpu_instance_id = Some(struct_.gpuInstanceId).filter(|id| *id != NO_VALUE);
255 let compute_instance_id = Some(struct_.computeInstanceId).filter(|id| *id != NO_VALUE);
256
257 Self {
258 pid: struct_.pid,
259 used_gpu_memory: UsedGpuMemory::from(struct_.usedGpuMemory),
260 gpu_instance_id,
261 compute_instance_id,
262 }
263 }
264}
265
266#[derive(Debug, Clone, Eq, PartialEq, Hash)]
269#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
270pub struct EccErrorCounts {
271 pub device_memory: u64,
272 pub l1_cache: u64,
273 pub l2_cache: u64,
274 pub register_file: u64,
275}
276
277impl From<nvmlEccErrorCounts_t> for EccErrorCounts {
278 fn from(struct_: nvmlEccErrorCounts_t) -> Self {
279 Self {
280 device_memory: struct_.deviceMemory,
281 l1_cache: struct_.l1Cache,
282 l2_cache: struct_.l2Cache,
283 register_file: struct_.registerFile,
284 }
285 }
286}
287
288#[derive(Debug, Clone, Eq, PartialEq, Hash)]
291#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
292pub struct MemoryInfo {
293 pub free: u64,
295
296 pub reserved: u64,
298
299 pub total: u64,
301 pub used: u64,
306
307 pub version: u32,
309}
310
311impl From<nvmlMemory_v2_t> for MemoryInfo {
312 fn from(struct_: nvmlMemory_v2_t) -> Self {
313 Self {
314 free: struct_.free,
315 reserved: struct_.reserved,
316 total: struct_.total,
317 used: struct_.used,
318 version: struct_.version,
319 }
320 }
321}
322
323#[derive(Debug, Clone, Eq, PartialEq, Hash)]
327#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
328pub struct Utilization {
329 pub gpu: u32,
332 pub memory: u32,
335}
336
337impl From<nvmlUtilization_t> for Utilization {
338 fn from(struct_: nvmlUtilization_t) -> Self {
339 Self {
340 gpu: struct_.gpu,
341 memory: struct_.memory,
342 }
343 }
344}
345
346#[derive(Debug, Clone, Eq, PartialEq, Hash)]
349#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
350pub struct ViolationTime {
351 pub reference_time: u64,
353 pub violation_time: u64,
355}
356
357impl From<nvmlViolationTime_t> for ViolationTime {
358 fn from(struct_: nvmlViolationTime_t) -> Self {
359 Self {
360 reference_time: struct_.referenceTime,
361 violation_time: struct_.violationTime,
362 }
363 }
364}
365
366#[derive(Debug, Clone, Eq, PartialEq, Hash)]
375#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
376pub struct AccountingStats {
377 pub gpu_utilization: Option<u32>,
386 pub is_running: bool,
388 pub max_memory_usage: Option<u64>,
392 pub memory_utilization: Option<u32>,
399 pub start_time: u64,
401 pub time: u64,
404}
405
406impl From<nvmlAccountingStats_t> for AccountingStats {
407 fn from(struct_: nvmlAccountingStats_t) -> Self {
408 let not_avail_u64 = (NVML_VALUE_NOT_AVAILABLE) as u64;
409 let not_avail_u32 = (NVML_VALUE_NOT_AVAILABLE) as u32;
410
411 #[allow(clippy::match_like_matches_macro)]
412 Self {
413 gpu_utilization: match struct_.gpuUtilization {
414 v if v == not_avail_u32 => None,
415 _ => Some(struct_.gpuUtilization),
416 },
417 is_running: match struct_.isRunning {
418 0 => false,
419 _ => true,
422 },
423 max_memory_usage: match struct_.maxMemoryUsage {
424 v if v == not_avail_u64 => None,
425 _ => Some(struct_.maxMemoryUsage),
426 },
427 memory_utilization: match struct_.memoryUtilization {
428 v if v == not_avail_u32 => None,
429 _ => Some(struct_.memoryUtilization),
430 },
431 start_time: struct_.startTime,
432 time: struct_.time,
433 }
434 }
435}
436
437#[derive(Debug, Clone, Eq, PartialEq, Hash)]
439#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
440pub struct EncoderSessionInfo {
441 pub session_id: u32,
443 pub pid: u32,
445 pub vgpu_instance: Option<u32>,
448 pub codec_type: EncoderType,
449 pub hres: u32,
451 pub vres: u32,
453 pub average_fps: u32,
455 pub average_latency: u32,
457}
458
459impl TryFrom<nvmlEncoderSessionInfo_t> for EncoderSessionInfo {
460 type Error = NvmlError;
461
462 fn try_from(value: nvmlEncoderSessionInfo_t) -> Result<Self, Self::Error> {
470 Ok(Self {
471 session_id: value.sessionId,
472 pid: value.pid,
473 vgpu_instance: match value.vgpuInstance {
474 0 => None,
475 other => Some(other),
476 },
477 codec_type: EncoderType::try_from(value.codecType)?,
478 hres: value.hResolution,
479 vres: value.vResolution,
480 average_fps: value.averageFps,
481 average_latency: value.averageLatency,
482 })
483 }
484}
485
486#[derive(Debug, Clone, PartialEq)]
489#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
490pub struct Sample {
491 pub timestamp: u64,
493 pub value: SampleValue,
494}
495
496impl Sample {
497 pub fn from_tag_and_struct(tag: &SampleValueType, struct_: nvmlSample_t) -> Self {
500 Self {
501 timestamp: struct_.timeStamp,
502 value: SampleValue::from_tag_and_union(tag, struct_.sampleValue),
503 }
504 }
505}
506
507#[derive(Debug, Clone, Eq, PartialEq, Hash)]
508#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
509pub struct ProcessUtilizationSample {
510 pub pid: u32,
511 pub timestamp: u64,
513 pub sm_util: u32,
515 pub mem_util: u32,
517 pub enc_util: u32,
519 pub dec_util: u32,
521}
522
523impl From<nvmlProcessUtilizationSample_t> for ProcessUtilizationSample {
524 fn from(struct_: nvmlProcessUtilizationSample_t) -> Self {
525 Self {
526 pid: struct_.pid,
527 timestamp: struct_.timeStamp,
528 sm_util: struct_.smUtil,
529 mem_util: struct_.memUtil,
530 enc_util: struct_.encUtil,
531 dec_util: struct_.decUtil,
532 }
533 }
534}
535
536#[derive(Debug)]
539pub struct FieldValueSample {
540 pub field: FieldId,
542 pub timestamp: i64,
544 pub latency: i64,
551 pub value: Result<SampleValue, NvmlError>,
555}
556
557impl TryFrom<nvmlFieldValue_t> for FieldValueSample {
558 type Error = NvmlError;
559
560 fn try_from(value: nvmlFieldValue_t) -> Result<Self, Self::Error> {
568 Ok(Self {
569 field: FieldId(value.fieldId),
570 timestamp: value.timestamp,
571 latency: value.latencyUsec,
572 value: match nvml_try(value.nvmlReturn) {
573 Ok(_) => Ok(SampleValue::from_tag_and_union(
574 &SampleValueType::try_from(value.valueType)?,
575 value.value,
576 )),
577 Err(e) => Err(e),
578 },
579 })
580 }
581}
582
583#[derive(Debug, Clone, Eq, PartialEq)]
585#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
586pub struct FbcStats {
587 pub sessions_count: u32,
589 pub average_fps: u32,
591 pub average_latency: u32,
593}
594
595impl From<nvmlFBCStats_t> for FbcStats {
596 fn from(struct_: nvmlFBCStats_t) -> Self {
597 Self {
598 sessions_count: struct_.sessionsCount,
599 average_fps: struct_.averageFPS,
600 average_latency: struct_.averageLatency,
601 }
602 }
603}
604
605#[derive(Debug, Clone, Eq, PartialEq)]
607#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
608pub struct FbcSessionInfo {
609 pub session_id: u32,
611 pub pid: u32,
613 pub vgpu_instance: Option<u32>,
616 pub display_ordinal: u32,
618 pub session_type: FbcSessionType,
620 pub session_flags: FbcFlags,
622 pub hres_max: u32,
624 pub vres_max: u32,
626 pub hres: u32,
628 pub vres: u32,
630 pub average_fps: u32,
632 pub average_latency: u32,
634}
635
636impl TryFrom<nvmlFBCSessionInfo_t> for FbcSessionInfo {
637 type Error = NvmlError;
638
639 fn try_from(value: nvmlFBCSessionInfo_t) -> Result<Self, Self::Error> {
649 Ok(Self {
650 session_id: value.sessionId,
651 pid: value.pid,
652 vgpu_instance: match value.vgpuInstance {
653 0 => None,
654 other => Some(other),
655 },
656 display_ordinal: value.displayOrdinal,
657 session_type: FbcSessionType::try_from(value.sessionType)?,
658 session_flags: FbcFlags::from_bits(value.sessionFlags)
659 .ok_or(NvmlError::IncorrectBits(Bits::U32(value.sessionFlags)))?,
660 hres_max: value.hMaxResolution,
661 vres_max: value.vMaxResolution,
662 hres: value.hResolution,
663 vres: value.vResolution,
664 average_fps: value.averageFPS,
665 average_latency: value.averageLatency,
666 })
667 }
668}
669
670#[derive(Debug, Clone, Eq, PartialEq, Hash)]
672#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
673pub struct DeviceAttributes {
674 pub multiprocessor_count: u32,
676 pub shared_copy_engine_count: u32,
678 pub shared_decoder_count: u32,
680 pub shared_encoder_count: u32,
682 pub shared_jpeg_count: u32,
684 pub shared_ofa_count: u32,
686 pub gpu_instance_slice_count: u32,
688 pub compute_instance_slice_count: u32,
690 pub memory_size_mb: u64,
692}
693
694impl From<nvmlDeviceAttributes_t> for DeviceAttributes {
695 fn from(struct_: nvmlDeviceAttributes_t) -> Self {
696 Self {
697 multiprocessor_count: struct_.multiprocessorCount,
698 shared_copy_engine_count: struct_.sharedCopyEngineCount,
699 shared_decoder_count: struct_.sharedDecoderCount,
700 shared_encoder_count: struct_.sharedEncoderCount,
701 shared_jpeg_count: struct_.sharedJpegCount,
702 shared_ofa_count: struct_.sharedOfaCount,
703 gpu_instance_slice_count: struct_.gpuInstanceSliceCount,
704 compute_instance_slice_count: struct_.computeInstanceSliceCount,
705 memory_size_mb: struct_.memorySizeMB,
706 }
707 }
708}
709
710#[derive(Debug, Clone, Eq, PartialEq, Hash)]
712#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
713pub struct FanSpeedInfo {
714 pub version: u32,
716 pub fan: u32,
718 pub speed: u32,
720}
721
722impl From<nvmlFanSpeedInfo_t> for FanSpeedInfo {
723 fn from(struct_: nvmlFanSpeedInfo_t) -> Self {
724 Self {
725 version: struct_.version,
726 fan: struct_.fan,
727 speed: struct_.speed,
728 }
729 }
730}
731
732#[derive(Debug, Clone, Eq, PartialEq)]
734#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
735pub struct ClockOffset {
736 pub version: u32,
738 pub clock_type: Clock,
739 pub state: PerformanceState,
740 pub clock_offset_mhz: i32,
741 pub min_clock_offset_mhz: i32,
742 pub max_clock_offset_mhz: i32,
743}
744
745impl TryFrom<nvmlClockOffset_v1_t> for ClockOffset {
746 type Error = NvmlError;
747
748 fn try_from(value: nvmlClockOffset_v1_t) -> Result<Self, Self::Error> {
749 Ok(Self {
750 version: value.version,
751 clock_type: Clock::try_from(value.type_)?,
752 state: PerformanceState::try_from(value.pstate)?,
753 clock_offset_mhz: value.clockOffsetMHz,
754 min_clock_offset_mhz: value.minClockOffsetMHz,
755 max_clock_offset_mhz: value.maxClockOffsetMHz,
756 })
757 }
758}
759
760#[derive(Debug, Clone, Eq, PartialEq)]
762#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
763pub struct ProfileInfo {
764 pub copy_engine_count: u32,
765 pub decoder_count: u32,
766 pub encoder_count: u32,
767 pub id: u32,
768 pub instance_count: u32,
769 pub is_p2p_supported: bool,
770 pub jpeg_count: u32,
771 pub memory_size_mb: u64,
772 pub multiprocessor_count: u32,
773 pub ofa_count: u32,
774 pub slice_count: u32,
775}
776
777impl From<nvmlGpuInstanceProfileInfo_t> for ProfileInfo {
778 fn from(struct_: nvmlGpuInstanceProfileInfo_t) -> Self {
779 Self {
780 copy_engine_count: struct_.copyEngineCount,
781 decoder_count: struct_.decoderCount,
782 encoder_count: struct_.encoderCount,
783 id: struct_.id,
784 instance_count: struct_.instanceCount,
785 is_p2p_supported: struct_.isP2pSupported > 0,
786 jpeg_count: struct_.jpegCount,
787 memory_size_mb: struct_.memorySizeMB,
788 multiprocessor_count: struct_.multiprocessorCount,
789 ofa_count: struct_.ofaCount,
790 slice_count: struct_.sliceCount,
791 }
792 }
793}
794
795#[derive(Debug, Clone, Eq, PartialEq)]
797#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
798pub struct GpuInstancePlacement {
799 pub size: u32,
801 pub start: u32,
803}
804
805impl From<nvmlGpuInstancePlacement_t> for GpuInstancePlacement {
806 fn from(value: nvmlGpuInstancePlacement_t) -> Self {
807 Self {
808 size: value.size,
809 start: value.start,
810 }
811 }
812}
813
814#[derive(Debug, Clone, Eq, PartialEq)]
817#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
818pub struct VgpuSchedulerCapabilities {
819 pub is_arr_mode_supported: bool,
821 pub max_avg_factor_for_arr: u32,
823 pub max_freq_for_arr: u32,
825 pub max_time_slice: u32,
827 pub min_avg_factor_for_arr: u32,
829 pub min_freq_for_arr: u32,
831 pub min_time_slice: u32,
833 pub supported_schedulers: Vec<u32>,
835}
836
837impl From<nvmlVgpuSchedulerCapabilities_t> for VgpuSchedulerCapabilities {
838 fn from(value: nvmlVgpuSchedulerCapabilities_t) -> Self {
839 let supported_schedulers = value.supportedSchedulers.to_vec();
840 Self {
841 is_arr_mode_supported: value.isArrModeSupported > 0,
842 max_avg_factor_for_arr: value.maxAvgFactorForARR,
843 max_freq_for_arr: value.maxFrequencyForARR,
844 max_time_slice: value.maxTimeslice,
845 min_avg_factor_for_arr: value.minAvgFactorForARR,
846 min_freq_for_arr: value.minFrequencyForARR,
847 min_time_slice: value.minTimeslice,
848 supported_schedulers,
849 }
850 }
851}
852
853#[derive(Debug, Clone, Eq, PartialEq)]
855#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
856pub struct VgpuVersion {
857 pub min: u32,
859 pub max: u32,
861}
862
863impl From<nvmlVgpuVersion_t> for VgpuVersion {
864 fn from(value: nvmlVgpuVersion_t) -> Self {
865 Self {
866 min: value.minVersion,
867 max: value.maxVersion,
868 }
869 }
870}
871
872impl VgpuVersion {
873 pub fn as_c(&self) -> nvmlVgpuVersion_t {
874 nvmlVgpuVersion_t {
875 minVersion: self.min,
876 maxVersion: self.max,
877 }
878 }
879}
880
881#[derive(Debug, Clone, Eq, PartialEq)]
883#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
884pub struct VgpuSchedulerParams {
885 pub avg_factor: Option<u32>,
886 pub timeslice: u32,
887}
888
889#[derive(Debug, Clone, Eq, PartialEq)]
891#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
892pub struct VgpuSchedulerLogEntry {
893 pub timestamp: u64,
895 pub time_run_total: u64,
897 pub time_run: u64,
899 pub sw_runlist_id: u32,
901 pub target_time_slice: u64,
903 pub cumulative_preemption_time: u64,
905}
906
907impl From<nvmlVgpuSchedulerLogEntry_t> for VgpuSchedulerLogEntry {
908 fn from(value: nvmlVgpuSchedulerLogEntry_t) -> Self {
909 Self {
910 timestamp: value.timestamp,
911 time_run_total: value.timeRunTotal,
912 time_run: value.timeRun,
913 sw_runlist_id: value.swRunlistId,
914 target_time_slice: value.targetTimeSlice,
915 cumulative_preemption_time: value.cumulativePreemptionTime,
916 }
917 }
918}
919
920#[derive(Debug, Clone, Eq, PartialEq)]
922#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
923pub struct VgpuSchedulerLog {
924 pub engine_id: u32,
926 pub scheduler_policy: u32,
928 pub arr_mode: u32,
930 pub scheduler_params: VgpuSchedulerParams,
931 pub entries_count: u32,
933 pub entries: Vec<VgpuSchedulerLogEntry>,
935}
936
937impl From<nvmlVgpuSchedulerLog_t> for VgpuSchedulerLog {
938 fn from(value: nvmlVgpuSchedulerLog_t) -> Self {
939 let entries = value
940 .logEntries
941 .iter()
942 .map(|e| VgpuSchedulerLogEntry::from(*e))
943 .collect::<Vec<_>>();
944 let params = match value.arrMode {
945 2 => {
946 let data = unsafe { value.schedulerParams.vgpuSchedDataWithARR };
947 VgpuSchedulerParams {
948 avg_factor: Some(data.avgFactor),
949 timeslice: data.timeslice,
950 }
951 }
952 _ => {
953 let data = unsafe { value.schedulerParams.vgpuSchedData };
954 VgpuSchedulerParams {
955 avg_factor: None,
956 timeslice: data.timeslice,
957 }
958 }
959 };
960
961 Self {
962 engine_id: value.engineId,
963 scheduler_policy: value.schedulerPolicy,
964 arr_mode: value.arrMode,
965 scheduler_params: params,
966 entries_count: entries.len() as u32,
967 entries,
968 }
969 }
970}
971
972#[derive(Debug, Clone, Eq, PartialEq)]
974#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
975pub struct VgpuSchedulerGetState {
976 pub arr_mode: u32,
978 pub scheduler_policy: u32,
980}
981
982impl From<nvmlVgpuSchedulerGetState_t> for VgpuSchedulerGetState {
983 fn from(value: nvmlVgpuSchedulerGetState_t) -> Self {
984 Self {
985 arr_mode: value.arrMode,
986 scheduler_policy: value.schedulerPolicy,
987 }
988 }
989}
990
991#[derive(Debug, Clone, Eq, PartialEq)]
992#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
993pub struct VgpuSchedulerSetParams {
994 pub avg_factor: Option<u32>,
996 pub frequency_or_timeslice: u32,
998}
999
1000impl VgpuSchedulerSetParams {
1001 pub fn as_c(&self) -> nvmlVgpuSchedulerSetParams_t {
1002 match self.avg_factor {
1003 Some(a) => nvmlVgpuSchedulerSetParams_t {
1004 vgpuSchedDataWithARR: nvmlVgpuSchedulerSetParams_t__bindgen_ty_1 {
1005 avgFactor: a,
1006 frequency: self.frequency_or_timeslice,
1007 },
1008 },
1009 _ => nvmlVgpuSchedulerSetParams_t {
1010 vgpuSchedData: nvmlVgpuSchedulerSetParams_t__bindgen_ty_2 {
1011 timeslice: self.frequency_or_timeslice,
1012 },
1013 },
1014 }
1015 }
1016}
1017
1018#[derive(Debug, Clone, Eq, PartialEq)]
1019#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1020pub struct VgpuSchedulerSetState {
1021 pub scheduler_policy: u32,
1022 pub enable_arr_mode: u32,
1023 pub scheduler_params: VgpuSchedulerSetParams,
1024}
1025
1026impl VgpuSchedulerSetState {
1027 pub fn as_c(&self) -> nvmlVgpuSchedulerSetState_t {
1028 nvmlVgpuSchedulerSetState_t {
1029 enableARRMode: self.enable_arr_mode,
1030 schedulerPolicy: self.scheduler_policy,
1031 schedulerParams: self.scheduler_params.as_c(),
1032 }
1033 }
1034}
1035
1036#[cfg(test)]
1037#[allow(unused_variables, unused_imports)]
1038mod tests {
1039 use crate::error::*;
1040 use crate::ffi::bindings::*;
1041 use crate::test_utils::*;
1042 use std::convert::TryInto;
1043 use std::mem;
1044
1045 #[test]
1046 fn pci_info_from_to_c() {
1047 let nvml = nvml();
1048 test_with_device(3, &nvml, |device| {
1049 let converted: nvmlPciInfo_t = device
1050 .pci_info()
1051 .expect("wrapped pci info")
1052 .try_into()
1053 .expect("converted c pci info");
1054
1055 let sym = nvml_sym(nvml.lib.nvmlDeviceGetPciInfo_v3.as_ref())?;
1056
1057 let raw = unsafe {
1058 let mut pci_info: nvmlPciInfo_t = mem::zeroed();
1059 nvml_try(sym(device.handle(), &mut pci_info)).expect("raw pci info");
1060 pci_info
1061 };
1062
1063 assert_eq!(converted.busId, raw.busId);
1064 assert_eq!(converted.domain, raw.domain);
1065 assert_eq!(converted.bus, raw.bus);
1066 assert_eq!(converted.device, raw.device);
1067 assert_eq!(converted.pciDeviceId, raw.pciDeviceId);
1068 assert_eq!(converted.pciSubSystemId, raw.pciSubSystemId);
1069
1070 Ok(())
1071 })
1072 }
1073}