use std::alloc::{GlobalAlloc, Layout, System};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum TensorAllocatorError {
#[error("Invalid tensor layout {0}")]
LayoutError(core::alloc::LayoutError),
#[error("Null pointer")]
NullPointer,
}
pub trait TensorAllocator: Clone {
fn alloc(&self, layout: Layout) -> Result<*mut u8, TensorAllocatorError>;
fn dealloc(&self, ptr: *mut u8, layout: Layout);
}
#[derive(Clone)]
pub struct CpuAllocator;
impl Default for CpuAllocator {
fn default() -> Self {
Self
}
}
impl TensorAllocator for CpuAllocator {
fn alloc(&self, layout: Layout) -> Result<*mut u8, TensorAllocatorError> {
let ptr = unsafe { System.alloc(layout) };
if ptr.is_null() {
Err(TensorAllocatorError::NullPointer)?
}
Ok(ptr)
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
fn dealloc(&self, ptr: *mut u8, layout: Layout) {
unsafe { System.dealloc(ptr, layout) }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cpu_allocator() -> Result<(), TensorAllocatorError> {
let allocator = CpuAllocator;
let layout = Layout::from_size_align(1024, 64).unwrap();
let ptr = allocator.alloc(layout)?;
allocator.dealloc(ptr, layout);
Ok(())
}
}