I am writing a low-level API, which needs to memory allocated by special allocation function.
This memory is accessble by both host and device
Here is my current implementation: (Detail omitted)
/// Marker traits for types that can be on device
/// Implemented for all primitive, non-reference types
pub unsafe trait DeviceCopy: Copy {}
/// Similar to `std::vec::Vec`, but use special memory alloc function
pub struct UnifiedBuffer<T: DeviceCopy> {
ptr: core::ptr::NonNull<T>,
len: usize,
}
/// New type for slice, which ensures the slice on unified memory
#[derive(Debug, Copy, Clone)]
pub struct UnifiedSlice<'a, T: DeviceCopy>(&'a [T]);
But the Deref
trait implementation confuses me.
It seems no way to Deref
from UnifiedBuffer
to UnifiedSlice
The compilable code:
impl<T: DeviceCopy> Deref for UnifiedBuffer<T> {
type Target = [T];
fn deref(&self) -> &[T] {
unsafe { core::slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
}
}
What do not work:
impl<'a, T: DeviceCopy> Deref for UnifiedBuffer<T>
type Target = UnifiedSlice<'a, T>;
fn deref(&self) -> &UnifiedSlice<'a, T> {
todo!();
}
}
Compilation errors with
the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
but how to solve it?
It there any special syntax to specify the lifetime?
Or am I writing wrong abstraction?
Alternative ideas:
- Declare
UnifiedSlice
as
pub struct UnifiedSlice<T: DeviceCopy>([T]);
instead of reference type
But I am not sure how to use this?
2. Declare UnifiedPtr
as new type of T
pub struct UnifiedPtr<T: DeviceCopy>(T);
and UnifiedBuffer
deref to [UnifiedPtr<T>]
,
but it does not looks like a abstraction for memory address.