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);
    }
}