#![allow(unused_unsafe)]
#![allow(non_camel_case_types)]
#![allow(clippy::wildcard_in_or_patterns)]
pub use opencl_sys::{
CL_PLATFORM_EXTENSIONS, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, CL_PLATFORM_HOST_TIMER_RESOLUTION,
CL_PLATFORM_NAME, CL_PLATFORM_NUMERIC_VERSION, CL_PLATFORM_PROFILE,
CL_PLATFORM_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR, CL_PLATFORM_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR,
CL_PLATFORM_SEMAPHORE_TYPES_KHR, CL_PLATFORM_VENDOR, CL_PLATFORM_VERSION, CL_SUCCESS, cl_int,
cl_name_version, cl_platform_id, cl_platform_info, cl_uint, cl_ulong, cl_version,
};
#[allow(unused_imports)]
use super::error_codes::DLOPEN_FUNCTION_NOT_AVAILABLE;
use super::info_type::InfoType;
use super::{api_info_size, api_info_value, api_info_vector};
use libc::{c_void, size_t};
use std::mem;
use std::ptr;
#[allow(unused_unsafe)]
pub fn get_platform_ids() -> Result<Vec<cl_platform_id>, cl_int> {
let mut count: cl_uint = 0;
let mut status = unsafe { cl_call!(clGetPlatformIDs(0, ptr::null_mut(), &raw mut count)) };
if CL_SUCCESS != status {
Err(status)
} else if 0 < count {
let len = count as usize;
let mut ids: Vec<cl_platform_id> = Vec::with_capacity(len);
unsafe {
status = cl_call!(clGetPlatformIDs(count, ids.as_mut_ptr(), ptr::null_mut()));
ids.set_len(len);
};
if CL_SUCCESS == status {
Ok(ids)
} else {
Err(status)
}
} else {
Ok(Vec::default())
}
}
pub fn get_platform_data(
platform: cl_platform_id,
param_name: cl_platform_info,
) -> Result<Vec<u8>, cl_int> {
api_info_size!(get_size, clGetPlatformInfo);
let size = get_size(platform, param_name)?;
api_info_vector!(get_vector, u8, clGetPlatformInfo);
get_vector(platform, param_name, size)
}
pub fn get_platform_info(
platform: cl_platform_id,
param_name: cl_platform_info,
) -> Result<InfoType, cl_int> {
match param_name {
CL_PLATFORM_NUMERIC_VERSION => {
api_info_value!(get_value, cl_uint, clGetPlatformInfo);
Ok(InfoType::Uint(get_value(platform, param_name)?))
}
CL_PLATFORM_HOST_TIMER_RESOLUTION => {
api_info_value!(get_value, cl_ulong, clGetPlatformInfo);
Ok(InfoType::Ulong(get_value(platform, param_name)?))
}
CL_PLATFORM_EXTENSIONS_WITH_VERSION => {
api_info_size!(get_size, clGetPlatformInfo);
let size = get_size(platform, param_name)?;
api_info_vector!(get_vec, cl_name_version, clGetPlatformInfo);
Ok(InfoType::VecNameVersion(get_vec(
platform, param_name, size,
)?))
}
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 => {
api_info_size!(get_size, clGetPlatformInfo);
api_info_vector!(get_vec, cl_uint, clGetPlatformInfo);
let size = get_size(platform, param_name)?;
Ok(InfoType::VecUshort(get_vec(platform, param_name, size)?))
}
CL_PLATFORM_PROFILE
| CL_PLATFORM_VERSION
| CL_PLATFORM_NAME
| CL_PLATFORM_VENDOR
| CL_PLATFORM_EXTENSIONS
| _ => Ok(InfoType::VecUchar(get_platform_data(platform, param_name)?)),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::error_codes::error_text;
#[test]
fn test_get_platform_info() {
let platform_ids = get_platform_ids().unwrap();
println!("Number of platforms: {}", platform_ids.len());
assert!(0 < platform_ids.len());
let platform_id = platform_ids[0];
let value = get_platform_info(platform_id, CL_PLATFORM_PROFILE).unwrap();
let value: String = value.into();
println!("CL_PLATFORM_PROFILE: {}", value);
assert!(!value.is_empty());
let value = get_platform_info(platform_id, CL_PLATFORM_VERSION).unwrap();
let value: String = value.into();
println!("CL_PLATFORM_VERSION: {}", value);
assert!(!value.is_empty());
let value = get_platform_info(platform_id, CL_PLATFORM_NAME).unwrap();
let value: String = value.into();
println!("CL_PLATFORM_NAME: {}", value);
assert!(!value.is_empty());
let value = get_platform_info(platform_id, CL_PLATFORM_VENDOR).unwrap();
let value: String = value.into();
println!("CL_PLATFORM_VENDOR: {}", value);
assert!(!value.is_empty());
let value = get_platform_info(platform_id, CL_PLATFORM_EXTENSIONS).unwrap();
let value: String = value.into();
println!("CL_PLATFORM_EXTENSIONS: {}", value);
assert!(!value.is_empty());
match get_platform_info(platform_id, CL_PLATFORM_HOST_TIMER_RESOLUTION) {
Ok(value) => {
let value = cl_ulong::from(value);
println!("CL_PLATFORM_HOST_TIMER_RESOLUTION: {}", value)
}
Err(e) => println!(
"OpenCL error, CL_PLATFORM_HOST_TIMER_RESOLUTION: {}",
error_text(e)
),
};
}
#[test]
fn test_get_platform_info_3_0() {
let platform_ids = get_platform_ids().unwrap();
let opencl_3: &str = "OpenCL 3";
let mut platform_3: Option<cl_platform_id> = None;
for id in platform_ids {
let value = get_platform_info(id, CL_PLATFORM_VERSION).unwrap();
let value: String = value.into();
if value.contains(opencl_3) {
platform_3 = Some(id);
break;
}
}
if let Some(platform_id) = platform_3 {
let value = get_platform_info(platform_id, CL_PLATFORM_NUMERIC_VERSION).unwrap();
let value = cl_uint::from(value);
println!("CL_PLATFORM_NUMERIC_VERSION: {}", value);
assert!(0 < value);
let value =
get_platform_info(platform_id, CL_PLATFORM_EXTENSIONS_WITH_VERSION).unwrap();
println!("CL_PLATFORM_EXTENSIONS_WITH_VERSION: {}", value);
let value = Vec::<cl_name_version>::from(value);
println!("CL_PLATFORM_EXTENSIONS_WITH_VERSION count: {}", value.len());
assert!(0 < value.len());
}
}
}