1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
extern crate libc; use std::fmt::Display; use std::mem::{transmute, size_of}; use array::{NDData, NDDataMut, NDArray, NDSlice, NDSliceMut}; pub trait SizedBuffer { unsafe fn get_raw_ptr(&self) -> *const libc::c_void; fn get_raw_size(&self) -> usize; } pub trait SizedBufferMut : SizedBuffer { unsafe fn get_raw_ptr_mut(&mut self) -> *mut libc::c_void; } pub trait ComputeBackend { fn init(&mut self) -> Result<(),String>; fn create_array(&mut self, size : usize) -> Result<u32,String>; fn set_array(&self, id : u32, array : &SizedBuffer) -> Result<(),String>; fn get_array(&self, id : u32, array : &mut SizedBufferMut) -> Result<(),String>; fn delete_array(&mut self, id : u32) -> Result<(),String>; fn finalize(&mut self) -> Result<(),String>; } pub struct ArrayRegistry<T : Clone> { array_list : Vec<T>, array_size : Vec<usize>, free_list : Vec<usize>, } impl<T> SizedBuffer for NDArray<T> { unsafe fn get_raw_ptr(&self) -> *const libc::c_void { transmute(self.get_data().as_ptr()) } fn get_raw_size(&self) -> usize { self.size() * size_of::<T>() } } impl<T : Clone + Display> SizedBufferMut for NDArray<T> where NDArray<T> : SizedBuffer { unsafe fn get_raw_ptr_mut(&mut self) -> *mut libc::c_void { transmute(self.get_data_mut().as_mut_ptr()) } } impl<'a, T> SizedBuffer for NDSliceMut<'a, T> { unsafe fn get_raw_ptr(&self) -> *const libc::c_void { transmute(self.get_data().as_ptr()) } fn get_raw_size(&self) -> usize { self.size() * size_of::<T>() } } impl<'a, T : Clone + Display> SizedBufferMut for NDSliceMut<'a, T> where NDSliceMut<'a, T> : SizedBuffer { unsafe fn get_raw_ptr_mut(&mut self) -> *mut libc::c_void { transmute(self.get_data_mut().as_mut_ptr()) } } impl<'a, T> SizedBuffer for NDSlice<'a, T> { unsafe fn get_raw_ptr(&self) -> *const libc::c_void { transmute(self.get_data().as_ptr()) } fn get_raw_size(&self) -> usize { self.size() * size_of::<T>() } } impl<T : Sized + Clone> ArrayRegistry<T> { pub fn new() -> ArrayRegistry<T> { ArrayRegistry::<T> { array_list : Vec::<T>::new(), array_size : Vec::<usize>::new(), free_list : Vec::<usize>::new(), } } pub fn register_array(&mut self, array : T, size : usize) -> u32 { if size == 0 { panic!("Attempting to register an emtpy array"); } if let Some(idx) = self.free_list.pop() { self.array_list[idx] = array.clone(); return idx as u32; } else { self.array_list.push(array.clone()); self.array_size.push(size); return (self.array_list.len() - 1) as u32; } } pub fn get_array(&self, id : u32) -> T { if id as usize >= self.array_list.len() { panic!("Querying array id {} which is not in the ArrayRegistry", id); } if self.array_size[id as usize] == 0 { panic!("Querying array id {} which has already been unregistered", id); } return self.array_list[id as usize].clone(); } pub fn get_array_size(&self, id : u32) -> usize { if id as usize >= self.array_list.len() { panic!("Querying array id {} which is not in the ArrayRegistry", id); } return self.array_size[id as usize]; } pub fn unregister_array(&mut self, id : u32) { if id as usize >= self.array_list.len() { panic!("Unregistering array id {} which is not in the ArrayRegistry", id); } self.array_size[id as usize] = 0; self.free_list.push(id as usize); } }