1#![allow(unused_unsafe)]
18#![allow(non_camel_case_types)]
19#![allow(clippy::wildcard_in_or_patterns)]
20
21pub use opencl_sys::{
22 CL_PLATFORM_EXTENSIONS, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
23 CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, CL_PLATFORM_HOST_TIMER_RESOLUTION,
24 CL_PLATFORM_NAME, CL_PLATFORM_NUMERIC_VERSION, CL_PLATFORM_PROFILE,
25 CL_PLATFORM_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR, CL_PLATFORM_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR,
26 CL_PLATFORM_SEMAPHORE_TYPES_KHR, CL_PLATFORM_VENDOR, CL_PLATFORM_VERSION, CL_SUCCESS, cl_int,
27 cl_name_version, cl_platform_id, cl_platform_info, cl_uint, cl_ulong, cl_version,
28};
29
30#[allow(unused_imports)]
31use super::error_codes::DLOPEN_FUNCTION_NOT_AVAILABLE;
32use super::info_type::InfoType;
33use super::{api_info_size, api_info_value, api_info_vector};
34
35use libc::{c_void, size_t};
36use std::mem;
37use std::ptr;
38
39#[allow(unused_unsafe)]
52pub fn get_platform_ids() -> Result<Vec<cl_platform_id>, cl_int> {
53 let mut count: cl_uint = 0;
55 let mut status = unsafe { cl_call!(clGetPlatformIDs(0, ptr::null_mut(), &raw mut count)) };
56
57 if CL_SUCCESS != status {
58 Err(status)
59 } else if 0 < count {
60 let len = count as usize;
62 let mut ids: Vec<cl_platform_id> = Vec::with_capacity(len);
63 unsafe {
64 status = cl_call!(clGetPlatformIDs(count, ids.as_mut_ptr(), ptr::null_mut()));
65 ids.set_len(len);
66 };
67
68 if CL_SUCCESS == status {
69 Ok(ids)
70 } else {
71 Err(status)
72 }
73 } else {
74 Ok(Vec::default())
75 }
76}
77
78pub fn get_platform_data(
81 platform: cl_platform_id,
82 param_name: cl_platform_info,
83) -> Result<Vec<u8>, cl_int> {
84 api_info_size!(get_size, clGetPlatformInfo);
85 let size = get_size(platform, param_name)?;
86 api_info_vector!(get_vector, u8, clGetPlatformInfo);
87 get_vector(platform, param_name, size)
88}
89
90pub fn get_platform_info(
120 platform: cl_platform_id,
121 param_name: cl_platform_info,
122) -> Result<InfoType, cl_int> {
123 match param_name {
124 CL_PLATFORM_NUMERIC_VERSION => {
126 api_info_value!(get_value, cl_uint, clGetPlatformInfo);
127 Ok(InfoType::Uint(get_value(platform, param_name)?))
128 }
129
130 CL_PLATFORM_HOST_TIMER_RESOLUTION => {
132 api_info_value!(get_value, cl_ulong, clGetPlatformInfo);
133 Ok(InfoType::Ulong(get_value(platform, param_name)?))
134 }
135
136 CL_PLATFORM_EXTENSIONS_WITH_VERSION => {
138 api_info_size!(get_size, clGetPlatformInfo);
139 let size = get_size(platform, param_name)?;
140 api_info_vector!(get_vec, cl_name_version, clGetPlatformInfo);
141 Ok(InfoType::VecNameVersion(get_vec(
142 platform, param_name, size,
143 )?))
144 }
145
146 CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR | CL_PLATFORM_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR | CL_PLATFORM_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR | CL_PLATFORM_SEMAPHORE_TYPES_KHR => {
151 api_info_size!(get_size, clGetPlatformInfo);
152 api_info_vector!(get_vec, cl_uint, clGetPlatformInfo);
153 let size = get_size(platform, param_name)?;
154 Ok(InfoType::VecUshort(get_vec(platform, param_name, size)?))
155 }
156
157 CL_PLATFORM_PROFILE
158 | CL_PLATFORM_VERSION
159 | CL_PLATFORM_NAME
160 | CL_PLATFORM_VENDOR
161 | CL_PLATFORM_EXTENSIONS
162 | _ => Ok(InfoType::VecUchar(get_platform_data(platform, param_name)?)),
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169 use crate::error_codes::error_text;
170
171 #[test]
172 fn test_get_platform_info() {
173 let platform_ids = get_platform_ids().unwrap();
174 println!("Number of platforms: {}", platform_ids.len());
175 assert!(0 < platform_ids.len());
176
177 let platform_id = platform_ids[0];
179
180 let value = get_platform_info(platform_id, CL_PLATFORM_PROFILE).unwrap();
181 let value: String = value.into();
182 println!("CL_PLATFORM_PROFILE: {}", value);
183 assert!(!value.is_empty());
184
185 let value = get_platform_info(platform_id, CL_PLATFORM_VERSION).unwrap();
186 let value: String = value.into();
187 println!("CL_PLATFORM_VERSION: {}", value);
188 assert!(!value.is_empty());
189
190 let value = get_platform_info(platform_id, CL_PLATFORM_NAME).unwrap();
191 let value: String = value.into();
192 println!("CL_PLATFORM_NAME: {}", value);
193 assert!(!value.is_empty());
194
195 let value = get_platform_info(platform_id, CL_PLATFORM_VENDOR).unwrap();
196 let value: String = value.into();
197 println!("CL_PLATFORM_VENDOR: {}", value);
198 assert!(!value.is_empty());
199
200 let value = get_platform_info(platform_id, CL_PLATFORM_EXTENSIONS).unwrap();
201 let value: String = value.into();
202 println!("CL_PLATFORM_EXTENSIONS: {}", value);
203 assert!(!value.is_empty());
204
205 match get_platform_info(platform_id, CL_PLATFORM_HOST_TIMER_RESOLUTION) {
207 Ok(value) => {
208 let value = cl_ulong::from(value);
209 println!("CL_PLATFORM_HOST_TIMER_RESOLUTION: {}", value)
210 }
211 Err(e) => println!(
212 "OpenCL error, CL_PLATFORM_HOST_TIMER_RESOLUTION: {}",
213 error_text(e)
214 ),
215 };
216 }
217
218 #[test]
219 fn test_get_platform_info_3_0() {
220 let platform_ids = get_platform_ids().unwrap();
221
222 let opencl_3: &str = "OpenCL 3";
224 let mut platform_3: Option<cl_platform_id> = None;
225 for id in platform_ids {
226 let value = get_platform_info(id, CL_PLATFORM_VERSION).unwrap();
227 let value: String = value.into();
228 if value.contains(opencl_3) {
229 platform_3 = Some(id);
230 break;
231 }
232 }
233
234 if let Some(platform_id) = platform_3 {
235 let value = get_platform_info(platform_id, CL_PLATFORM_NUMERIC_VERSION).unwrap();
236 let value = cl_uint::from(value);
237 println!("CL_PLATFORM_NUMERIC_VERSION: {}", value);
238 assert!(0 < value);
239
240 let value =
241 get_platform_info(platform_id, CL_PLATFORM_EXTENSIONS_WITH_VERSION).unwrap();
242 println!("CL_PLATFORM_EXTENSIONS_WITH_VERSION: {}", value);
243
244 let value = Vec::<cl_name_version>::from(value);
245 println!("CL_PLATFORM_EXTENSIONS_WITH_VERSION count: {}", value.len());
246 assert!(0 < value.len());
247 }
248 }
249}