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
//! Cpu device and allocation

use std::{
    alloc::{AllocError, Allocator, Global, Layout},
    ops::{Deref, DerefMut},
};

use crate::ptr::reef::Ref;

use super::{DefaultDeviceAllocator, Device, DeviceAllocator, DevicePtr, NonNull};

#[derive(Debug)]
/// The default device
pub struct Cpu;

impl Device for Cpu {
    type Ptr<T: ?Sized> = *mut T;
    const IS_CPU: bool = true;

    fn copy_from_host<T: Copy>(from: &[T], to: &mut Ref<[T], Self>) {
        to.deref_mut().copy_from_slice(from)
    }

    fn copy_to_host<T: Copy>(from: &Ref<[T], Self>, to: &mut [T]) {
        to.copy_from_slice(from.deref())
    }

    fn copy<T: Copy>(from: &Ref<[T], Self>, to: &mut Ref<[T], Self>) {
        to.deref_mut().copy_from_slice(from.deref())
    }
}

impl DefaultDeviceAllocator for Cpu {
    type Alloc = Global;
}

impl<T: ?Sized> DevicePtr<T> for *mut T {
    fn as_raw(self) -> *mut T {
        self
    }

    fn from_raw(ptr: *mut T) -> Self {
        ptr
    }

    unsafe fn write(self, val: T)
    where
        T: Sized,
    {
        self.write(val)
    }
}

impl<T: ?Sized> From<std::ptr::NonNull<T>> for NonNull<T, Cpu> {
    fn from(ptr: std::ptr::NonNull<T>) -> Self {
        unsafe { NonNull::new_unchecked(ptr.as_ptr()) }
    }
}

impl<T: ?Sized> From<NonNull<T, Cpu>> for std::ptr::NonNull<T> {
    fn from(ptr: NonNull<T, Cpu>) -> Self {
        unsafe { std::ptr::NonNull::new_unchecked(ptr.as_ptr()) }
    }
}

impl<A: Allocator> DeviceAllocator for A {
    type AllocError = AllocError;
    type Device = Cpu;

    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8], Cpu>, AllocError> {
        self.allocate(layout).map(NonNull::from)
    }

    fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8], Cpu>, AllocError> {
        self.allocate_zeroed(layout).map(NonNull::from)
    }

    unsafe fn deallocate(&self, ptr: NonNull<u8, Cpu>, layout: Layout) {
        self.deallocate(ptr.into(), layout)
    }

    unsafe fn grow(
        &self,
        ptr: NonNull<u8, Cpu>,
        old_layout: Layout,
        new_layout: Layout,
    ) -> Result<NonNull<[u8], Cpu>, AllocError> {
        self.grow(ptr.into(), old_layout, new_layout)
            .map(NonNull::from)
    }

    unsafe fn grow_zeroed(
        &self,
        ptr: NonNull<u8, Cpu>,
        old_layout: Layout,
        new_layout: Layout,
    ) -> Result<NonNull<[u8], Cpu>, AllocError> {
        self.grow_zeroed(ptr.into(), old_layout, new_layout)
            .map(NonNull::from)
    }

    unsafe fn shrink(
        &self,
        ptr: NonNull<u8, Cpu>,
        old_layout: Layout,
        new_layout: Layout,
    ) -> Result<NonNull<[u8], Cpu>, AllocError> {
        self.shrink(ptr.into(), old_layout, new_layout)
            .map(NonNull::from)
    }
}