baracuda_types/
version.rs1use core::fmt;
8
9#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
11#[repr(transparent)]
12pub struct CudaVersion(u32);
13
14impl CudaVersion {
15 pub const CUDA_11_4: Self = Self::from_major_minor(11, 4);
17 pub const CUDA_11_8: Self = Self::from_major_minor(11, 8);
19 pub const CUDA_12_0: Self = Self::from_major_minor(12, 0);
21 pub const CUDA_12_3: Self = Self::from_major_minor(12, 3);
23 pub const CUDA_12_6: Self = Self::from_major_minor(12, 6);
25 pub const CUDA_12_8: Self = Self::from_major_minor(12, 8);
27 pub const CUDA_13_0: Self = Self::from_major_minor(13, 0);
29
30 pub const FLOOR: Self = Self::CUDA_11_4;
32
33 #[inline]
35 pub const fn from_major_minor(major: u32, minor: u32) -> Self {
36 Self(major * 1000 + minor * 10)
37 }
38
39 #[inline]
42 pub const fn from_raw(raw: u32) -> Self {
43 Self(raw)
44 }
45
46 #[inline]
48 pub const fn raw(self) -> u32 {
49 self.0
50 }
51
52 #[inline]
54 pub const fn major(self) -> u32 {
55 self.0 / 1000
56 }
57
58 #[inline]
60 pub const fn minor(self) -> u32 {
61 (self.0 % 1000) / 10
62 }
63
64 #[inline]
66 pub const fn at_least(self, major: u32, minor: u32) -> bool {
67 self.0 >= major * 1000 + minor * 10
68 }
69}
70
71impl fmt::Display for CudaVersion {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 write!(f, "CUDA {}.{}", self.major(), self.minor())
74 }
75}
76
77#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
82#[non_exhaustive]
83pub enum Feature {
84 StreamOrderedAllocator,
86 VirtualMemoryManagement,
88 LibraryManagement,
90 GreenContexts,
92 MulticastObjects,
94 GraphConditionalNodes,
96 GraphSwitchNodes,
98 CudaLaunchKernelEx,
100 NvJitLink,
102 TensorMapObjects,
104 RuntimeLogBuffer,
106 CudaInitDevice,
108 RuntimeGreenContexts,
110}
111
112impl Feature {
113 pub const fn required_version(self) -> CudaVersion {
115 match self {
116 Feature::StreamOrderedAllocator => CudaVersion::from_major_minor(11, 2),
117 Feature::VirtualMemoryManagement => CudaVersion::from_major_minor(10, 2),
118 Feature::LibraryManagement => CudaVersion::CUDA_12_0,
119 Feature::GreenContexts => CudaVersion::CUDA_12_0,
120 Feature::MulticastObjects => CudaVersion::CUDA_12_0,
121 Feature::GraphConditionalNodes => CudaVersion::CUDA_12_3,
122 Feature::GraphSwitchNodes => CudaVersion::CUDA_12_8,
123 Feature::CudaLaunchKernelEx => CudaVersion::CUDA_12_0,
124 Feature::NvJitLink => CudaVersion::CUDA_12_0,
125 Feature::TensorMapObjects => CudaVersion::from_major_minor(11, 8),
126 Feature::RuntimeLogBuffer => CudaVersion::CUDA_12_0,
127 Feature::CudaInitDevice => CudaVersion::CUDA_12_0,
128 Feature::RuntimeGreenContexts => CudaVersion::from_major_minor(13, 1),
129 }
130 }
131}
132
133#[inline]
136pub const fn supports(version: CudaVersion, feature: Feature) -> bool {
137 version.raw() >= feature.required_version().raw()
138}
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143
144 #[test]
145 fn encode_decode() {
146 let v = CudaVersion::from_major_minor(12, 6);
147 assert_eq!(v.major(), 12);
148 assert_eq!(v.minor(), 6);
149 assert_eq!(v.raw(), 12060);
150 }
151
152 #[test]
153 fn ordering_is_by_version() {
154 assert!(CudaVersion::CUDA_11_4 < CudaVersion::CUDA_12_0);
155 assert!(CudaVersion::CUDA_12_0 < CudaVersion::CUDA_13_0);
156 }
157
158 #[test]
159 fn at_least() {
160 assert!(CudaVersion::CUDA_12_6.at_least(12, 0));
161 assert!(!CudaVersion::CUDA_11_4.at_least(12, 0));
162 }
163
164 #[test]
165 fn feature_gating() {
166 assert!(supports(CudaVersion::CUDA_12_0, Feature::GreenContexts));
167 assert!(!supports(CudaVersion::CUDA_11_8, Feature::GreenContexts));
168 assert!(supports(CudaVersion::CUDA_12_8, Feature::GraphSwitchNodes));
169 assert!(!supports(CudaVersion::CUDA_12_6, Feature::GraphSwitchNodes));
170 }
171
172 #[test]
173 fn floor_is_consistent() {
174 assert_eq!(CudaVersion::FLOOR, CudaVersion::CUDA_11_4);
175 }
176}