use {Alloc, ComputeDevice, ErrorKind, Memory, Result, Shape, Synch, Viewable};
use std::os::raw::c_void;
use super::OpenCLMemory;
use super::super::{foreign, high};
use utility;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct OpenCLDevice {
pub(super) device: high::Device,
pub(super) context: high::Context,
pub(super) queue: high::Queue,
}
impl OpenCLDevice {
pub fn queue(&self) -> &high::Queue {
&self.queue
}
}
impl Viewable for OpenCLDevice {
fn view(&self) -> ComputeDevice {
ComputeDevice::OpenCL(self.clone())
}
}
impl<T> Alloc<T> for OpenCLDevice {
fn alloc(&self, shape: &Shape) -> Result<Memory<T>> {
let flag = foreign::CL_MEM_READ_WRITE;
let length = shape.capacity();
let size = utility::allocated::<T>(length);
let buffer = self.context.create_buffer(flag, size, None)?;
let cl_buffer = OpenCLMemory { buf: buffer };
Ok(Memory::OpenCL(cl_buffer))
}
fn allocwrite(&self, shape: &Shape, mut data: Vec<T>) -> Result<Memory<T>> {
let flag = foreign::CL_MEM_READ_ONLY | foreign::CL_MEM_COPY_HOST_PTR;
let length = shape.capacity();
let size = utility::allocated::<T>(length);
let pointer = data.as_mut_ptr();
let buffer = self.context.create_buffer(flag, size, pointer as *mut c_void)?;
let cl_buffer = OpenCLMemory { buf: buffer };
Ok(Memory::OpenCL(cl_buffer))
}
}
impl<T> Synch<T> for OpenCLDevice {
fn write(&self, memory: &mut Memory<T>, _: &ComputeDevice, source: &Memory<T>) -> Result {
match *source {
Memory::Native(ref native_memory) => {
let cl_memory = unsafe { memory.as_opencl_unchecked() };
let length = native_memory.len();
let size = utility::allocated::<T>(length);
let slice = native_memory.as_slice_memory_order().unwrap();
let slice_pointer = slice.as_ptr();
let ref buf = cl_memory.buf;
let block = true; let offset = 0;
let _ = self.queue
.enqueue_write_buffer(buf, block, offset, size, slice_pointer as *const c_void, &[])?;
Ok(())
},
_ => Err(ErrorKind::NoAvailableSynchronizationRouteFound.into()),
}
}
fn read(&self, memory: &Memory<T>, _: &mut ComputeDevice, destination: &mut Memory<T>) -> Result {
match *destination {
Memory::Native(ref mut native_memory) => {
let cl_memory = unsafe { memory.as_opencl_unchecked() };
let length = native_memory.len();
let size = utility::allocated::<T>(length);
let slice = native_memory.as_slice_memory_order_mut().unwrap();
let slice_pointer = slice.as_mut_ptr();
let ref buf = cl_memory.buf;
let block = true; let offset = 0;
let _ = self.queue
.enqueue_read_buffer(buf, block, offset, size, slice_pointer as *mut c_void, &[])?;
Ok(())
},
_ => Err(ErrorKind::NoAvailableSynchronizationRouteFound.into()),
}
}
}