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
use {Alloc, ComputeDevice, Memory, Result, Shape, Synch, Viewable};
use super::NativeMemory;

/// The native device.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct NativeDevice;

impl Viewable for NativeDevice {

    fn view(&self) -> ComputeDevice {
        ComputeDevice::Native(NativeDevice)
    }
}

impl<T> Alloc<T> for NativeDevice {


    fn alloc(&self, shape: &Shape) -> Result<Memory<T>> {
        // TODO

        let mut buffer = Vec::with_capacity(shape.capacity);

        unsafe {
            buffer.set_len(shape.capacity);
        }

        Ok(Memory::Native(
            NativeMemory::from_shape_vec(
                &shape.dims[..], 
                buffer).unwrap()))
    }

    fn allocwrite(&self, shape: &Shape, data: Vec<T>) -> Result<Memory<T>> {
        // TODO

        Ok(Memory::Native(
            NativeMemory::from_shape_vec(
                &shape.dims[..], 
                data).unwrap()))
    }
}

impl<T> Synch<T> for NativeDevice where T: Clone {

    fn write(
        &self, 
        memory: &mut Memory<T>, 
        src_device: &ComputeDevice, 
        source: &Memory<T>) 
    -> Result {

        match *src_device {
            ComputeDevice::Native(_) => {
                let memory = unsafe { memory.as_mut_native_unchecked() };
                let source = unsafe { source.as_native_unchecked() };
                // > Array implements .clone_from() to reuse an array's existing allocation. 
                // > Semantically equivalent to *self = other.clone(), but potentially more efficient.
                Ok(memory.clone_from(source))
            },

            ComputeDevice::OpenCL(ref cl_device) => {
                cl_device.read(source, &mut ComputeDevice::Native(NativeDevice), memory)
            }
        }
    }

    fn read(
        &self, 
        memory: &Memory<T>, 
        dest_device: &mut ComputeDevice, 
        destination: &mut Memory<T>) 
    -> Result {

        match *dest_device {
            ComputeDevice::Native(_) => {
                let source = unsafe { memory.as_native_unchecked() };
                let destination = unsafe { destination.as_mut_native_unchecked() };
                // > Array implements .clone_from() to reuse an array's existing allocation. 
                // > Semantically equivalent to *self = other.clone(), but potentially more efficient.
                Ok(destination.clone_from(source))
            },

            ComputeDevice::OpenCL(ref mut cl_device) => {
                cl_device.write(destination, &ComputeDevice::Native(NativeDevice), memory)
            }
        }
    }
}