1use libc::{intptr_t, size_t};
16use opencl_sys::{
17 CL_LUID_SIZE_KHR, CL_UUID_SIZE_KHR, cl_image_format, cl_int, cl_name_version, cl_uchar,
18 cl_uint, cl_ulong,
19};
20use std::fmt;
21
22#[derive(Debug)]
31pub enum InfoType {
32 Int(i32),
33 Uint(u32),
34 Ulong(u64),
35 Size(usize),
36 Ptr(isize),
37 Luid([u8; CL_LUID_SIZE_KHR]),
38 Uuid([u8; CL_UUID_SIZE_KHR]),
39 VecUchar(Vec<u8>),
40 VecUshort(Vec<u32>),
41 VecUlong(Vec<u64>),
42 VecSize(Vec<usize>),
43 VecIntPtr(Vec<isize>),
44 VecNameVersion(Vec<cl_name_version>),
45 VecImageFormat(Vec<cl_image_format>),
46 VecVecUchar(Vec<Vec<u8>>),
47}
48
49macro_rules! match_info_type {
51 ($value:expr, $variant:path) => {
52 match $value {
53 $variant(x) => x,
54 _ => panic!("value is not an {}", stringify!($variant)),
55 }
56 };
57}
58
59impl From<InfoType> for i32 {
60 fn from(value: InfoType) -> Self {
61 match_info_type!(value, InfoType::Int)
62 }
63}
64
65impl From<InfoType> for u32 {
66 fn from(value: InfoType) -> Self {
67 match_info_type!(value, InfoType::Uint)
68 }
69}
70
71impl From<InfoType> for u64 {
72 fn from(value: InfoType) -> Self {
73 match_info_type!(value, InfoType::Ulong)
74 }
75}
76
77impl From<InfoType> for usize {
78 fn from(value: InfoType) -> Self {
79 match_info_type!(value, InfoType::Size)
80 }
81}
82
83impl From<InfoType> for isize {
84 fn from(value: InfoType) -> Self {
85 match_info_type!(value, InfoType::Ptr)
86 }
87}
88
89impl From<InfoType> for [u8; CL_LUID_SIZE_KHR] {
90 fn from(value: InfoType) -> Self {
91 match_info_type!(value, InfoType::Luid)
92 }
93}
94
95impl From<InfoType> for [u8; CL_UUID_SIZE_KHR] {
96 fn from(value: InfoType) -> Self {
97 match_info_type!(value, InfoType::Uuid)
98 }
99}
100
101impl From<InfoType> for Vec<u8> {
102 fn from(value: InfoType) -> Self {
103 match_info_type!(value, InfoType::VecUchar)
104 }
105}
106
107impl From<InfoType> for Vec<u32> {
108 fn from(value: InfoType) -> Self {
109 match_info_type!(value, InfoType::VecUshort)
110 }
111}
112
113impl From<InfoType> for Vec<u64> {
114 fn from(value: InfoType) -> Self {
115 match_info_type!(value, InfoType::VecUlong)
116 }
117}
118
119impl From<InfoType> for Vec<usize> {
120 fn from(value: InfoType) -> Self {
121 match_info_type!(value, InfoType::VecSize)
122 }
123}
124
125impl From<InfoType> for Vec<isize> {
126 fn from(value: InfoType) -> Self {
127 match_info_type!(value, InfoType::VecIntPtr)
128 }
129}
130
131impl From<InfoType> for Vec<cl_name_version> {
132 fn from(value: InfoType) -> Self {
133 match_info_type!(value, InfoType::VecNameVersion)
134 }
135}
136
137impl From<InfoType> for Vec<cl_image_format> {
138 fn from(value: InfoType) -> Self {
139 match_info_type!(value, InfoType::VecImageFormat)
140 }
141}
142
143impl From<InfoType> for Vec<Vec<u8>> {
144 fn from(value: InfoType) -> Self {
145 match_info_type!(value, InfoType::VecVecUchar)
146 }
147}
148
149impl From<InfoType> for String {
150 fn from(info_type: InfoType) -> Self {
156 let mut a = Vec::<u8>::from(info_type);
157
158 while a.last() == Some(&0) {
160 a.pop();
161 }
162
163 Self::from_utf8_lossy(&a).into_owned()
165 }
166}
167
168impl fmt::Display for InfoType {
169 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
170 match self {
171 Self::VecUchar(a) => {
172 let b = String::from_utf8_lossy(a).into_owned();
173 write!(f, "{b}")
174 }
175
176 Self::Luid(a) => {
179 write!(
180 f,
181 "{:x}{:x}-{:x}{:x}{:x}{:x}{:x}{:x}",
182 a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]
183 )
184 }
185
186 Self::Uuid(a) => {
188 write!(
189 f,
190 "{:x}{:x}{:x}{:x}-{:x}{:x}-{:x}{:x}-{:x}{:x}-{:x}{:x}{:x}{:x}{:x}{:x}",
191 a[0],
192 a[1],
193 a[2],
194 a[3],
195 a[4],
196 a[5],
197 a[6],
198 a[7],
199 a[8],
200 a[9],
201 a[10],
202 a[11],
203 a[12],
204 a[13],
205 a[14],
206 a[15],
207 )
208 }
209
210 Self::VecNameVersion(a) => {
211 let mut s = String::default();
212 for b in a {
213 s.push('\n');
214
215 s.push_str(&b.version.to_string());
216 s.push_str(": ");
217 s.push_str(&String::from_utf8_lossy(&b.name));
218 }
219
220 write!(f, "{s}")
221 }
222
223 Self::VecImageFormat(a) => {
224 let mut s = String::default();
225
226 for b in a {
227 s.push('\n');
228
229 s.push_str(&b.image_channel_order.to_string());
230 s.push_str(": ");
231 s.push_str(&b.image_channel_data_type.to_string());
232 }
233
234 write!(f, "{s}")
235 }
236
237 Self::VecVecUchar(a) => {
240 let mut s = String::default();
241 for b in a {
242 s.push('\n');
243 s.push_str(&String::from_utf8_lossy(b));
244 }
245
246 write!(f, "{s}")
247 }
248
249 _ => panic!("not a Displayable type, use Debug instead"),
250 }
251 }
252}
253
254impl InfoType {
255 #[must_use]
256 pub fn to_int(self) -> cl_int {
257 i32::from(self)
258 }
259
260 #[must_use]
261 pub fn to_uint(self) -> cl_uint {
262 u32::from(self)
263 }
264
265 #[must_use]
266 pub fn to_ulong(self) -> cl_ulong {
267 u64::from(self)
268 }
269
270 #[must_use]
271 pub fn to_size(self) -> size_t {
272 usize::from(self)
273 }
274
275 #[must_use]
276 pub fn to_ptr(self) -> intptr_t {
277 isize::from(self)
278 }
279
280 #[must_use]
281 pub fn to_luid(self) -> [u8; CL_LUID_SIZE_KHR] {
282 self.into()
283 }
284
285 #[must_use]
286 pub fn to_uuid(self) -> [u8; CL_UUID_SIZE_KHR] {
287 self.into()
288 }
289
290 #[must_use]
291 pub fn to_vec_uchar(self) -> Vec<cl_uchar> {
292 Vec::<u8>::from(self)
293 }
294
295 #[must_use]
296 pub fn to_vec_ulong(self) -> Vec<cl_ulong> {
297 Vec::<u64>::from(self)
298 }
299
300 #[must_use]
301 pub fn to_vec_size(self) -> Vec<size_t> {
302 Vec::<usize>::from(self)
303 }
304
305 #[must_use]
306 pub fn to_vec_intptr(self) -> Vec<intptr_t> {
307 Vec::<isize>::from(self)
308 }
309
310 #[must_use]
311 pub fn to_vec_name_version(self) -> Vec<cl_name_version> {
312 Vec::<cl_name_version>::from(self)
313 }
314
315 #[must_use]
316 pub fn to_vec_image_format(self) -> Vec<cl_image_format> {
317 Vec::<cl_image_format>::from(self)
318 }
319
320 #[must_use]
321 pub fn to_vec_vec_uchar(self) -> Vec<Vec<cl_uchar>> {
322 Vec::<Vec<u8>>::from(self)
323 }
324}
325#[cfg(test)]
326mod tests {
327 use crate::device::{
328 CL_DEVICE_MAX_WORK_ITEM_SIZES, CL_DEVICE_NAME, CL_DEVICE_PARTITION_PROPERTIES,
329 CL_DEVICE_TYPE, CL_DEVICE_TYPE_ALL, CL_DEVICE_VENDOR_ID, CL_DRIVER_VERSION, get_device_ids,
330 get_device_info,
331 };
332 use crate::platform::{
333 CL_PLATFORM_NAME, CL_PLATFORM_VERSION, get_platform_ids, get_platform_info,
334 };
335
336 #[test]
337 fn test_debug_display_info() {
338 let platform_ids = get_platform_ids().unwrap();
339 println!("Number of platforms: {}", platform_ids.len());
340 assert!(0 < platform_ids.len());
341
342 let platform_id = platform_ids[0];
344
345 let value = get_platform_info(platform_id, CL_PLATFORM_NAME).unwrap();
347 println!("CL_PLATFORM_NAME: {}", value);
348
349 let value = get_platform_info(platform_id, CL_PLATFORM_VERSION).unwrap();
350 println!("CL_PLATFORM_VERSION: {}", value);
351
352 let device_ids = get_device_ids(platform_id, CL_DEVICE_TYPE_ALL).unwrap();
353 println!("Platform[0]->number of devices: {}", device_ids.len());
354 assert!(0 < device_ids.len());
355
356 let device_id = device_ids[0];
358
359 let value = get_device_info(device_id, CL_DEVICE_NAME).unwrap();
360 println!("CL_DEVICE_NAME: {}", value);
361
362 let value = get_device_info(device_id, CL_DRIVER_VERSION).unwrap();
363 println!("CL_DRIVER_VERSION: {}", value);
364
365 let value = get_device_info(device_id, CL_DEVICE_TYPE).unwrap();
367 println!("CL_DEVICE_TYPE: {:?}", value);
368
369 let value = get_device_info(device_id, CL_DEVICE_VENDOR_ID).unwrap();
370 println!("CL_DEVICE_VENDOR_ID: {:?}", value);
371
372 let value = get_device_info(device_id, CL_DEVICE_MAX_WORK_ITEM_SIZES).unwrap();
373 println!("CL_DEVICE_MAX_WORK_ITEM_SIZES len: {:?}", value);
374
375 let value = get_device_info(device_id, CL_DEVICE_PARTITION_PROPERTIES).unwrap();
376 println!("CL_DEVICE_PARTITION_PROPERTIES: {:?}", value);
377 }
378}