use crate::runtime::Env;
use obwio::*;
pub struct Buffer {
pub buffer: cl_mem,
pub data: Vec<f32>,
}
impl Buffer {
pub fn to(&mut self, env: &mut Env) {
let mut data = self.data.clone();
to_gpu(env, &mut data, self);
}
pub fn from(&mut self, data: &mut Vec<f32>, env: &mut Env) {
from_gpu(env, data, self);
}
pub fn new(env: &mut Env, data: &[f32]) -> Buffer {
buffer_write(env, data)
}
}
impl Drop for Buffer {
fn drop(&mut self) {
cleanvar(self);
}
}
fn buffer_write(env: &mut Env, data: &[f32]) -> Buffer {
unsafe {
let size = data.len() * std::mem::size_of::<f32>();
let buf = clCreateBuffer(
env.context,
CL_MEM_READ_WRITE.into(),
size,
std::ptr::null_mut(),
&mut env.err,
);
if env.err != 0 {
panic!("OpenCL error: {}", env.err);
}
Buffer {
buffer: buf,
data: data.to_vec(),
}
}
}
fn to_gpu(env: &mut Env, data: &mut Vec<f32>, buffer: &mut Buffer) {
unsafe {
let size = data.len() * std::mem::size_of::<f32>();
clEnqueueWriteBuffer(
env.queue,
buffer.buffer,
CL_TRUE,
0,
size,
data.as_ptr() as *const _,
0,
std::ptr::null_mut(),
std::ptr::null_mut(),
);
if env.err != 0 {
panic!("OpenCL error: {}", env.err);
}
}
}
fn from_gpu(env: &mut Env, data: &mut Vec<f32>, buf: &mut Buffer) {
unsafe {
let size = data.len() * std::mem::size_of::<f32>();
clEnqueueReadBuffer(
env.queue,
buf.buffer,
CL_TRUE,
0,
size,
data.as_mut_ptr() as *mut _,
0,
std::ptr::null_mut(),
std::ptr::null_mut(),
);
if env.err != 0 {
panic!("OpenCL error: {}", env.err);
}
}
}
fn cleanvar(buf: &mut Buffer) {
unsafe {
clReleaseMemObject(buf.buffer);
}
}