extern crate ocl;
extern crate ocl_extras;
use ocl::{Buffer, MemFlags, ProQue};
const RESULTS_TO_PRINT: usize = 20;
const WORK_SIZE: usize = 1 << 20;
const COEFF: f32 = 5432.1;
static KERNEL_SRC: &'static str = r#"
__kernel void multiply_by_scalar(
__private float const coeff,
__global float const* const src,
__global float* const res)
{
uint const idx = get_global_id(0);
res[idx] = src[idx] * coeff;
}
"#;
fn basics() -> ocl::Result<()> {
let ocl_pq = ProQue::builder()
.src(KERNEL_SRC)
.dims(WORK_SIZE)
.build()
.expect("Build ProQue");
let vec_source = ocl_extras::scrambled_vec((0.0, 20.0), ocl_pq.dims().to_len());
let source_buffer = Buffer::builder()
.queue(ocl_pq.queue().clone())
.flags(MemFlags::new().read_write())
.len(WORK_SIZE)
.copy_host_slice(&vec_source)
.build()?;
let mut vec_result = vec![0.0f32; WORK_SIZE];
let result_buffer: Buffer<f32> = ocl_pq.create_buffer()?;
let kern = ocl_pq
.kernel_builder("multiply_by_scalar")
.arg(COEFF)
.arg(None::<&Buffer<f32>>)
.arg_named("result", None::<&Buffer<f32>>)
.build()?;
kern.set_arg("result", &result_buffer)?;
kern.set_arg(0, &COEFF)?;
kern.set_arg(1, Some(&source_buffer))?;
kern.set_arg(2, &result_buffer)?;
println!(
"Kernel global work size: {:?}",
kern.default_global_work_size()
);
unsafe {
kern.enq()?;
}
result_buffer.read(&mut vec_result).enq()?;
for idx in 0..WORK_SIZE {
if idx < RESULTS_TO_PRINT {
println!(
"source[{idx}]: {:.03}, \t coeff: {}, \tresult[{idx}]: {}",
vec_source[idx],
COEFF,
vec_result[idx],
idx = idx
);
}
assert_eq!(vec_source[idx] * COEFF, vec_result[idx]);
}
Ok(())
}
pub fn main() {
match basics() {
Ok(_) => (),
Err(err) => println!("{}", err),
}
}