rusty_cl/
types.rs

1use std::fmt::{Display, Formatter};
2use std::ops::{BitAnd, BitOr, Not};
3use std::str::FromStr;
4
5/// cl_platform_id
6pub type PlatformId = usize;
7
8/// cl_device_id
9pub type DeviceId = usize;
10
11/// cl_platform_info
12#[derive(Eq, PartialEq, Copy, Clone)]
13#[cfg_attr(test, derive(Debug))]
14#[repr(u32)]
15pub enum PlatformInfo {
16    /// Either `"FULL_PROFILE"` or `"EMBEDDED_PROFILE"`.
17    Profile = 0x0900,
18    /// OpenCL version string.
19    Version = 0x0901,
20    /// Platform name string.
21    Name = 0x0902,
22    /// Platform vendor string.
23    Vendor = 0x0903,
24    /// Space-separated list of extension names (the extension names themselves do not contain any spaces) supported by the platform.
25    Extensions = 0x0904,
26}
27
28/// Device type to query/filter for or type of a given device.
29#[derive(Eq, PartialEq, Copy, Clone)]
30#[cfg_attr(test, derive(Debug))]
31#[repr(transparent)]
32pub struct DeviceType(u64);
33
34impl DeviceType {
35    /// The default device of the given platform.
36    pub const DEFAULT: Self = DeviceType(1 << 0);
37    /// A CPU.
38    pub const CPU: Self = DeviceType(1 << 1);
39    /// A GPGPU.
40    pub const GPU: Self = DeviceType(1 << 2);
41    /// A dedicated compute card.
42    pub const ACCELERATOR: Self = DeviceType(1 << 3);
43    /// A custom device.
44    pub const CUSTOM: Self = DeviceType(1 << 4);
45    /// All device types.
46    pub const ALL: Self = DeviceType(0xFFFFFFFF);
47
48    /// Get the raw underlying value.
49    pub fn raw(&self) -> u64 {
50        unsafe { std::mem::transmute_copy(self) }
51    }
52}
53
54impl BitOr for DeviceType {
55    type Output = Self;
56
57    fn bitor(self, rhs: Self) -> Self::Output {
58        Self(self.0 | rhs.0)
59    }
60}
61
62impl BitAnd for DeviceType {
63    type Output = Self;
64
65    fn bitand(self, rhs: Self) -> Self::Output {
66        Self(self.0 & rhs.0)
67    }
68}
69
70impl Not for DeviceType {
71    type Output = Self;
72
73    fn not(self) -> Self::Output {
74        Self((!self.0) & DeviceType::ALL.0)
75    }
76}
77
78/// An OpenCL profile (Full or embedded).
79#[derive(Eq, PartialEq, Copy, Clone)]
80#[cfg_attr(test, derive(Debug))]
81pub enum Profile {
82    /// The implementation supports the OpenCL specification.
83    Full,
84
85    /// The implementation supports the OpenCL embedded profile.
86    /// The embedded profile is defined to be a subset for each version of OpenCL.
87    Embedded,
88}
89
90impl TryFrom<String> for Profile {
91    type Error = String;
92
93    fn try_from(value: String) -> Result<Self, Self::Error> {
94        match value.as_str() {
95            "FULL_PROFILE" => Ok(Profile::Full),
96            "EMBEDDED_PROFILE" => Ok(Profile::Embedded),
97            _ => Err(value),
98        }
99    }
100}
101
102impl Display for Profile {
103    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
104        match *self {
105            Profile::Full => write!(f, "FULL_PROFILE"),
106            Profile::Embedded => write!(f, "EMBEDDED_PROFILE"),
107        }
108    }
109}
110
111/// OpenCL Version information.
112#[derive(Clone, Eq, PartialEq)]
113#[cfg_attr(test, derive(Debug))]
114pub struct Version {
115    /// The OpenCL major version.
116    major: u8,
117
118    /// The OpenCL minor version.
119    minor: u8,
120
121    /// Platform specific additional version information.
122    extra: Option<String>,
123}
124
125impl Version {
126    /// The OpenCL major version.
127    pub fn major(&self) -> u8 {
128        self.major
129    }
130
131    /// The OpenCL minor version.
132    pub fn minor(&self) -> u8 {
133        self.minor
134    }
135
136    /// Platform specific additional version information.
137    pub fn extra(&self) -> &Option<String> {
138        &self.extra
139    }
140}
141
142impl TryFrom<String> for Version {
143    type Error = String;
144
145    fn try_from(value: String) -> Result<Self, Self::Error> {
146        let parts: Vec<&str> = value.splitn(3, " ").collect();
147        if !(2..=3).contains(&parts.len()) || parts[0] != "OpenCL" {
148            return Err(value);
149        }
150
151        let (major_str, minor_str) = parts[1].split_once('.').ok_or_else(|| value.clone())?;
152        let major = u8::from_str(major_str).or_else(|_| Err(value.clone()))?;
153        let minor = u8::from_str(minor_str).or_else(|_| Err(value.clone()))?;
154
155        let extra = if parts.len() == 3 {
156            Some(parts[2].to_string())
157        } else {
158            None
159        };
160
161        Ok(Version { major, minor, extra })
162    }
163}
164
165impl Display for Version {
166    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
167        match self.extra() {
168            Some(extra) => write!(f, "OpenCL {}.{} {}", self.major, self.minor, extra),
169            None => write!(f, "OpenCL {}.{}", self.major, self.minor),
170        }
171    }
172}