1use crate::queue::Queue;
10
11use allocator_api2::alloc::{AllocError, Allocator};
12use sycl_rs_sys::usm::ffi;
13
14use std::{alloc::Layout, marker::PhantomData, ptr::NonNull};
15
16type CxxResult<T> = cxx::core::result::Result<T, cxx::Exception>;
17
18pub struct UsmAllocator<T: UsmAllocatorKind> {
20 queue: Queue,
21 _kind: PhantomData<T>,
22}
23
24pub unsafe trait UsmAlloc: Allocator {}
28
29unsafe impl<T: UsmAllocatorKind> UsmAlloc for UsmAllocator<T> {}
30
31pub trait UsmAllocatorKind {
32 unsafe fn alloc(alignment: usize, num_bytes: usize, queue: &Queue) -> CxxResult<*mut u8>;
36}
37
38pub unsafe trait HostAccessible {}
43
44impl<T: UsmAllocatorKind> From<&Queue> for UsmAllocator<T> {
45 fn from(queue: &Queue) -> Self {
46 Self {
47 queue: queue.clone(),
48 _kind: PhantomData,
49 }
50 }
51}
52
53unsafe impl<T: UsmAllocatorKind> Allocator for UsmAllocator<T> {
54 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
55 let ptr = unsafe { T::alloc(layout.align(), layout.size(), &self.queue) }
56 .map_err(|_e| AllocError)?;
57
58 let ptr = NonNull::new(ptr).ok_or(AllocError)?;
59 let slice = NonNull::slice_from_raw_parts(ptr, layout.size());
60
61 Ok(slice)
62 }
63
64 unsafe fn deallocate(&self, ptr: NonNull<u8>, _layout: Layout) {
65 unsafe {
66 ffi::free(ptr.as_ptr(), &self.queue.0);
67 }
68 }
69}
70
71#[allow(dead_code)]
75pub struct DeviceAllocator;
76
77impl UsmAllocatorKind for DeviceAllocator {
78 unsafe fn alloc(alignment: usize, num_bytes: usize, queue: &Queue) -> CxxResult<*mut u8> {
79 unsafe { ffi::aligned_alloc_device(alignment, num_bytes, &queue.0) }
80 }
81}
82
83pub struct HostAllocator;
85
86impl UsmAllocatorKind for HostAllocator {
87 unsafe fn alloc(alignment: usize, num_bytes: usize, queue: &Queue) -> CxxResult<*mut u8> {
88 unsafe { ffi::aligned_alloc_host(alignment, num_bytes, &queue.0) }
89 }
90}
91
92unsafe impl HostAccessible for UsmAllocator<HostAllocator> {}
93
94pub struct SharedAllocator;
96
97impl UsmAllocatorKind for SharedAllocator {
98 unsafe fn alloc(alignment: usize, num_bytes: usize, queue: &Queue) -> CxxResult<*mut u8> {
99 unsafe { ffi::aligned_alloc_shared(alignment, num_bytes, &queue.0) }
100 }
101}
102
103unsafe impl HostAccessible for UsmAllocator<SharedAllocator> {}