extern crate libc;
extern crate ocl;
extern crate find_folder;
use libc::c_void;
use find_folder::Search;
use ocl::{util, core, ProQue, Program, Buffer, EventList};
use ocl::cl_h::{cl_event, cl_int};
const ITERATIONS: usize = 8;
const PRINT_DEBUG: bool = true;
const RESULTS_TO_PRINT: usize = 5;
struct TestEventsStuff {
seed_vec: *const Vec<u32>,
result_vec: *const Vec<u32>,
data_set_size: usize,
addend: u32,
itr: usize,
}
extern fn _test_events_verify_result(event: cl_event, status: cl_int, user_data: *mut c_void) {
let buncha_stuff = user_data as *const TestEventsStuff;
unsafe {
let seed_vec: *const Vec<u32> = (*buncha_stuff).seed_vec as *const Vec<u32>;
let result_vec: *const Vec<u32> = (*buncha_stuff).result_vec as *const Vec<u32>;
let data_set_size: usize = (*buncha_stuff).data_set_size;
let addend: u32 = (*buncha_stuff).addend;
let itr: usize = (*buncha_stuff).itr;
if PRINT_DEBUG { println!("\nEvent: `{:?}` has completed with status: `{}`, data_set_size: '{}`, \
addend: {}, itr: `{}`.", event, status, data_set_size, addend, itr); }
for idx in 0..data_set_size {
assert_eq!((*result_vec)[idx],
((*seed_vec)[idx] + ((itr + 1) as u32) * addend));
if PRINT_DEBUG && (idx < RESULTS_TO_PRINT) {
let correct_result = (*seed_vec)[idx] + (((itr + 1) as u32) * addend);
print!("correct_result: {}, result_vec[{idx}]:{}\n",
correct_result, (*result_vec)[idx], idx = idx);
}
}
let mut errors_found = 0;
for idx in 0..data_set_size {
assert_eq!((*result_vec)[idx],
((*seed_vec)[idx] + ((itr + 1) as u32) * addend));
if PRINT_DEBUG {
let correct_result = (*seed_vec)[idx] + (((itr + 1) as u32) * addend);
if (*result_vec)[idx] != correct_result {
print!("correct_result:{}, result_vec[{idx}]:{}\n",
correct_result, (*result_vec)[idx], idx = idx);
errors_found += 1;
}
}
}
if PRINT_DEBUG {
if errors_found > 0 { print!("TOTAL ERRORS FOUND: {}\n", errors_found); }
}
}
}
fn main() {
let dims = [2 << 17];
let src_file = Search::ParentsThenKids(3, 3).for_folder("examples").unwrap().join("cl/kernel_file.cl");
let ocl_pq = ProQue::builder()
.dims(dims)
.prog_bldr(Program::builder().src_file(src_file))
.build().unwrap();
let seed_vec = util::scrambled_vec((0u32, 500u32), ocl_pq.dims().to_len());
let seed_buffer = Buffer::new(ocl_pq.queue(), Some(core::MEM_READ_WRITE |
core::MEM_COPY_HOST_PTR), ocl_pq.dims().clone(), Some(&seed_vec)).unwrap();
let mut result_vec = vec![0; dims[0]];
let mut result_buffer = Buffer::<u32>::new(ocl_pq.queue(), None,
ocl_pq.dims(), None).unwrap();
let addend = 11u32;
let mut kernel = ocl_pq.create_kernel("add_scalar").unwrap()
.gws(&dims)
.arg_buf_named("src", Some(&seed_buffer))
.arg_scl(addend)
.arg_buf(&mut result_buffer);
let mut kernel_event = EventList::new();
let mut buncha_stuffs = Vec::<TestEventsStuff>::with_capacity(ITERATIONS);
for itr in 0..ITERATIONS {
buncha_stuffs.push(TestEventsStuff {
seed_vec: &seed_vec as *const Vec<u32>,
result_vec: &result_vec as *const Vec<u32>,
data_set_size: dims[0],
addend: addend,
itr: itr,
});
if itr != 0 {
kernel.set_arg_buf_named("src", Some(&result_buffer)).unwrap();
}
if PRINT_DEBUG { println!("Enqueuing kernel [itr:{}]...", itr); }
kernel.cmd().enew(&mut kernel_event).enq().unwrap();
let mut read_event = EventList::new();
if PRINT_DEBUG { println!("Enqueuing read buffer [itr:{}]...", itr); }
unsafe { result_buffer.cmd().read_async(&mut result_vec)
.enew(&mut read_event).enq().unwrap(); }
let read_event = read_event.clone();
let last_idx = buncha_stuffs.len() - 1;
unsafe {
if PRINT_DEBUG { println!("Setting callback (verify_result, buncha_stuff[{}]) [i:{}]...",
last_idx, itr); }
read_event.set_callback(Some(_test_events_verify_result),
&mut buncha_stuffs[last_idx]).unwrap();
}
}
ocl_pq.queue().finish();
}