Skip to content

Commit ed76648

Browse files
feat: introduce useful util functions for cc and multi-gpu ppcie (#90)
Adds util functions for cc and multi-gpu ppcie
1 parent 6856c2d commit ed76648

File tree

2 files changed

+214
-0
lines changed

2 files changed

+214
-0
lines changed

nvml-wrapper/src/device.rs

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,188 @@ impl<'nvml> Device<'nvml> {
785785
}
786786
}
787787

788+
/**
789+
Checks simultaneously if confidential compute is enabled, if the device is in a production environment,
790+
and if the device is accepting client requests.
791+
# Errors
792+
* `Uninitialized`, if the library has not been successfully initialized
793+
* `NotSupported`, if this query is not supported by the device
794+
* `InvalidArg`, if confidential compute state is invalid
795+
*/
796+
pub fn check_confidential_compute_status(&self) -> Result<bool, NvmlError> {
797+
let cc_state_sym = nvml_sym(self.nvml.lib.nvmlSystemGetConfComputeState.as_ref())?;
798+
let cc_gpus_ready_sym = nvml_sym(
799+
self.nvml
800+
.lib
801+
.nvmlSystemGetConfComputeGpusReadyState
802+
.as_ref(),
803+
)?;
804+
805+
unsafe {
806+
let mut state: nvmlConfComputeSystemState_t = mem::zeroed();
807+
nvml_try(cc_state_sym(&mut state))?;
808+
809+
let is_cc_enabled = state.ccFeature == NVML_CC_SYSTEM_FEATURE_ENABLED;
810+
let is_prod_environment = state.environment == NVML_CC_SYSTEM_ENVIRONMENT_PROD;
811+
812+
let mut cc_gpus_ready: std::os::raw::c_uint = 0;
813+
nvml_try(cc_gpus_ready_sym(&mut cc_gpus_ready))?;
814+
let is_accepting_client_requests =
815+
cc_gpus_ready == NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE;
816+
817+
Ok(is_cc_enabled && is_prod_environment && is_accepting_client_requests)
818+
}
819+
}
820+
821+
/**
822+
Gets the confidential compute state for this `Device`.
823+
# Errors
824+
* `Uninitialized`, if the library has not been successfully initialized
825+
* `InvalidArg`, if device is invalid or memory is NULL
826+
* `NotSupported`, if this query is not supported by the device
827+
*/
828+
#[doc(alias = "nvmlDeviceGetConfComputeGpusReadyState")]
829+
pub fn get_confidential_compute_state(&self) -> Result<bool, NvmlError> {
830+
let sym = nvml_sym(
831+
self.nvml
832+
.lib
833+
.nvmlSystemGetConfComputeGpusReadyState
834+
.as_ref(),
835+
)?;
836+
837+
unsafe {
838+
let mut is_accepting_work: u32 = 0;
839+
nvml_try(sym(&mut is_accepting_work))?;
840+
Ok(is_accepting_work == NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE)
841+
}
842+
}
843+
844+
/**
845+
Sets the confidential compute state for this `Device`.
846+
# Errors
847+
* `Uninitialized`, if the library has not been successfully initialized
848+
* `InvalidArg`, if device is invalid or memory is NULL
849+
* `NotSupported`, if this query is not supported by the device
850+
*/
851+
#[doc(alias = "nvmlDeviceSetConfComputeState")]
852+
pub fn set_confidential_compute_state(&self, is_accepting_work: bool) -> Result<(), NvmlError> {
853+
let sym = nvml_sym(
854+
self.nvml
855+
.lib
856+
.nvmlSystemSetConfComputeGpusReadyState
857+
.as_ref(),
858+
)?;
859+
860+
unsafe {
861+
nvml_try(sym(is_accepting_work as u32))?;
862+
Ok(())
863+
}
864+
}
865+
866+
/**
867+
Gets the confidential compute state for this `Device`.
868+
# Errors
869+
870+
* `Uninitialized`, if the library has not been successfully initialized
871+
* `InvalidArg`, if device is invalid or counters is NULL
872+
* `NotSupported`, if the device does not support this feature
873+
* `GpuLost`, if the target GPU has fallen off the bus or is otherwise inaccessible
874+
* `ArgumentVersionMismatch`, if the provided version is invalid/unsupported
875+
* `Unknown`, on any unexpected error
876+
*/
877+
#[doc(alias = "nvmlDeviceSetConfComputeSettings")]
878+
pub fn is_cc_enabled(&self) -> Result<bool, NvmlError> {
879+
let sym = nvml_sym(self.nvml.lib.nvmlSystemGetConfComputeSettings.as_ref())?;
880+
881+
unsafe {
882+
let mut settings: nvmlSystemConfComputeSettings_t = mem::zeroed();
883+
nvml_try(sym(&mut settings))?;
884+
Ok(settings.ccFeature == NVML_CC_SYSTEM_FEATURE_ENABLED)
885+
}
886+
}
887+
888+
/**
889+
Gets the confidential compute state for this `Device`.
890+
# Errors
891+
892+
* `Uninitialized`, if the library has not been successfully initialized
893+
* `InvalidArg`, if device is invalid or counters is NULL
894+
* `NotSupported`, if the device does not support this feature
895+
* `GpuLost`, if the target GPU has fallen off the bus or is otherwise inaccessible
896+
* `ArgumentVersionMismatch`, if the provided version is invalid/unsupported
897+
* `Unknown`, on any unexpected error
898+
*/
899+
#[doc(alias = "nvmlSystemGetConfComputeSettings")]
900+
pub fn is_multi_gpu_protected_pcie_enabled(&self) -> Result<bool, NvmlError> {
901+
let sym = nvml_sym(self.nvml.lib.nvmlSystemGetConfComputeSettings.as_ref())?;
902+
903+
unsafe {
904+
let mut settings: nvmlSystemConfComputeSettings_t = mem::zeroed();
905+
nvml_try(sym(&mut settings))?;
906+
Ok(settings.multiGpuMode == NVML_CC_SYSTEM_MULTIGPU_PROTECTED_PCIE)
907+
}
908+
}
909+
910+
/**
911+
Gets the confidential compute state for this `Device`.
912+
# Errors
913+
914+
* `Uninitialized`, if the library has not been successfully initialized
915+
* `InvalidArg`, if device is invalid or counters is NULL
916+
* `NotSupported`, if the device does not support this feature
917+
* `GpuLost`, if the target GPU has fallen off the bus or is otherwise inaccessible
918+
* `ArgumentVersionMismatch`, if the provided version is invalid/unsupported
919+
* `Unknown`, on any unexpected error
920+
*/
921+
#[doc(alias = "nvmlSystemGetConfComputeSettings")]
922+
pub fn is_cc_dev_mode_enabled(&self) -> Result<bool, NvmlError> {
923+
let sym = nvml_sym(self.nvml.lib.nvmlSystemGetConfComputeSettings.as_ref())?;
924+
925+
unsafe {
926+
let mut settings: nvmlSystemConfComputeSettings_t = mem::zeroed();
927+
nvml_try(sym(&mut settings))?;
928+
Ok(settings.devToolsMode == NVML_CC_SYSTEM_DEVTOOLS_MODE_ON)
929+
}
930+
}
931+
932+
/**
933+
Gets the confidential compute capabilities for this `Device`.
934+
# Errors
935+
* `Uninitialized`, if the library has not been successfully initialized
936+
* `InvalidArg`, if device is invalid or memory is NULL
937+
* `NotSupported`, if this query is not supported by the device
938+
*/
939+
pub fn get_confidential_compute_capabilities(
940+
&self,
941+
) -> Result<ConfidentialComputeCapabilities, NvmlError> {
942+
let sym = nvml_sym(self.nvml.lib.nvmlSystemGetConfComputeCapabilities.as_ref())?;
943+
944+
unsafe {
945+
let mut capabilities: nvmlConfComputeSystemCaps_t = mem::zeroed();
946+
nvml_try(sym(&mut capabilities))?;
947+
948+
let cpu_caps = match capabilities.cpuCaps {
949+
NVML_CC_SYSTEM_CPU_CAPS_NONE => ConfidentialComputeCpuCapabilities::None,
950+
NVML_CC_SYSTEM_CPU_CAPS_AMD_SEV => ConfidentialComputeCpuCapabilities::AmdSev,
951+
NVML_CC_SYSTEM_CPU_CAPS_INTEL_TDX => ConfidentialComputeCpuCapabilities::IntelTdx,
952+
_ => return Err(NvmlError::Unknown),
953+
};
954+
955+
let gpus_caps = match capabilities.gpusCaps {
956+
NVML_CC_SYSTEM_GPUS_CC_CAPABLE => ConfidentialComputeGpuCapabilities::Capable,
957+
NVML_CC_SYSTEM_GPUS_CC_NOT_CAPABLE => {
958+
ConfidentialComputeGpuCapabilities::NotCapable
959+
}
960+
_ => return Err(NvmlError::Unknown),
961+
};
962+
963+
Ok(ConfidentialComputeCapabilities {
964+
cpu_caps,
965+
gpus_caps,
966+
})
967+
}
968+
}
969+
788970
/**
789971
Fetches the confidential compute attestation report for this [`Device`].
790972

nvml-wrapper/src/structs/device.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,38 @@ use crate::enum_wrappers::device::OperationMode;
44
#[cfg(feature = "serde")]
55
use serde_derive::{Deserialize, Serialize};
66

7+
/// Returned from `Device.get_confidential_compute_capabilities()`
8+
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
9+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10+
pub struct ConfidentialComputeCapabilities {
11+
/// The CPU capabilities.
12+
pub cpu_caps: ConfidentialComputeCpuCapabilities,
13+
/// The GPU capabilities.
14+
pub gpus_caps: ConfidentialComputeGpuCapabilities,
15+
}
16+
17+
/// The possible CPU capabilities for confidential compute (either None, AMD SEV or Intel TDX)
18+
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
19+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20+
pub enum ConfidentialComputeCpuCapabilities {
21+
/// No CPU capabilities.
22+
None,
23+
/// AMD SEV confidential compute capabilities.
24+
AmdSev,
25+
/// Intel TDX confidential compute capabilities.
26+
IntelTdx,
27+
}
28+
29+
/// The possible GPU capabilities for confidential compute (either not capable or capable)
30+
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
31+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
32+
pub enum ConfidentialComputeGpuCapabilities {
33+
/// Capable.
34+
Capable,
35+
/// Not capable.
36+
NotCapable,
37+
}
38+
739
/// Returned from `Device.confidential_compute_gpu_attestation_report_bytes()`
840
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
941
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]

0 commit comments

Comments
 (0)