Last active
February 23, 2021 22:57
-
-
Save Youka/f1b505875aa0ec914dce5bde97107f03 to your computer and use it in GitHub Desktop.
Rust OCL crate usage example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[cfg(feature = "gpgpu")] | |
mod gpgpu { | |
// Imports | |
use ocl::{ | |
Platform, | |
Device, | |
enums::{ | |
PlatformInfo, | |
DeviceInfo | |
}, | |
ProQue | |
}; | |
#[test] | |
fn test_ocl_support() { | |
// Information buffer | |
let mut info = vec![]; | |
// Iterate through available OpenCL platforms | |
info.push("\tPlatforms:".to_owned()); | |
for (platform_index, platform) in Platform::list().into_iter().enumerate() { | |
info.push(format!("\t\t{}:", platform_index)); | |
// Save platform information | |
for platform_info_key in &[ | |
PlatformInfo::Name, | |
PlatformInfo::Vendor, | |
PlatformInfo::Version, | |
PlatformInfo::Profile, | |
PlatformInfo::Extensions | |
] { | |
if let Ok(platform_info_value) = platform.info(*platform_info_key) { | |
info.push(format!("\t\t\t{:?}: {}", platform_info_key, platform_info_value)); | |
} | |
} | |
// Iterate through available OpenCL devices by platform | |
if let Ok(platform_devices) = Device::list_all(platform) { | |
info.push("\t\t\tDevices:".to_owned()); | |
for (device_index, device) in platform_devices.into_iter().enumerate() { | |
info.push(format!("\t\t\t\t{}:", device_index)); | |
// Save device information | |
for device_info_key in &[ | |
DeviceInfo::Type, | |
DeviceInfo::Name, | |
DeviceInfo::Vendor, | |
DeviceInfo::DriverVersion, | |
DeviceInfo::OpenclCVersion, | |
DeviceInfo::Profile, | |
DeviceInfo::MaxComputeUnits, | |
DeviceInfo::MaxWorkGroupSize, | |
DeviceInfo::AddressBits, | |
DeviceInfo::ImageSupport, | |
DeviceInfo::MaxSamplers, | |
DeviceInfo::MemBaseAddrAlign, | |
DeviceInfo::EndianLittle, | |
DeviceInfo::Available, | |
DeviceInfo::BuiltInKernels, | |
DeviceInfo::ParentDevice | |
] { | |
if let Ok(device_info_value) = device.info(*device_info_key) { | |
info.push(format!("\t\t\t\t\t{:?}: {}", device_info_key, device_info_value)); | |
} | |
} | |
} | |
} | |
} | |
// List default platform & devices | |
info.push(format!("\tDefault platform: {:?}", Platform::list().into_iter().position(|platform| *platform == *Platform::default() ).expect("Default platform missing?!"))); | |
info.push(format!("\tDevice specifier: {:?}", Device::specifier())); | |
// Print collected information | |
println!("OpenCL support:\n{}", info.join("\n")); | |
} | |
#[test] | |
fn test_ocl_kernel() { | |
// Create GPU processing queue | |
let pro_que = ProQue::builder() | |
.src(r##" | |
__kernel void fill(__global unsigned char* buffer, unsigned char value) { | |
buffer[get_global_id(0)] = value; | |
} | |
"##) | |
.dims(1920 * 1080 * 3) // Number of iterations per run / size of buffers | |
.build().expect("Couldn't build processing queue!"); | |
// Create GPU buffer | |
let buffer = pro_que.create_buffer::<u8>().expect("Couldn't create buffer!"); | |
// Create kernel instance on processing queue | |
let kernel = pro_que.kernel_builder("fill") | |
.arg(&buffer) | |
.arg(255u8) | |
.build().expect("Couldn't instantiate kernel!"); | |
// Execute kernel | |
unsafe { | |
kernel.enq().expect("Couldn't enqueue kernel for execution!"); | |
} | |
// Read buffer from GPU to CPU | |
let mut data = vec![0u8; buffer.len()]; | |
buffer.read(&mut data).enq().expect("Couldn't enqueue buffer reading operation!"); | |
// Check buffer after kernel execution | |
assert_eq!(data.len(), pro_que.dims().to_len()); | |
assert_eq!(data.last(), Some(&255u8)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment