use core::ffi::c_void;
use core::sync::atomic::Ordering;
use mnemosyne_core::MemoryBackend;
use super::registry::CUDA_DEVICE_ALLOCATIONS;
use super::{CudaAllocOps, CudaAllocationRegistry, loader, managed_raw_alloc, managed_raw_free};
pub struct CudaDeviceBackend;
impl CudaAllocOps for CudaDeviceBackend {
#[inline]
fn registry() -> &'static CudaAllocationRegistry {
&CUDA_DEVICE_ALLOCATIONS
}
#[inline]
fn alloc_sym() -> *mut c_void {
loader::CU_MEM_ALLOC_MANAGED.load(Ordering::Acquire)
}
#[inline]
fn free_sym() -> *mut c_void {
loader::CU_MEM_FREE.load(Ordering::Acquire)
}
#[inline]
unsafe fn raw_alloc(alloc_sym: *mut c_void, size: usize) -> *mut u8 {
unsafe { managed_raw_alloc(alloc_sym, size) }
}
#[inline]
unsafe fn raw_free(free_sym: *mut c_void, ptr: *mut u8) -> core::ffi::c_int {
unsafe { managed_raw_free(free_sym, ptr) }
}
#[inline]
unsafe fn post_register(ptr: *mut u8, size: usize) {
let advise_sym = loader::CU_MEM_ADVISE.load(Ordering::Acquire);
if advise_sym.is_null() {
return;
}
type CuMemAdviseFn = unsafe extern "system" fn(u64, usize, u32, i32) -> core::ffi::c_int;
let cu_mem_advise: CuMemAdviseFn = unsafe { core::mem::transmute(advise_sym) };
let _advise_status = unsafe { cu_mem_advise(ptr as u64, size, 3, 0) };
}
}
impl_cuda_memory_backend!(CudaDeviceBackend);
#[inline(always)]
unsafe fn allocate_device_tier(size: usize) -> *mut u8 {
unsafe { CudaDeviceBackend::allocate(size) }
}
#[inline(always)]
unsafe fn deallocate_device_tier(ptr: *mut u8, size: usize) -> bool {
unsafe { CudaDeviceBackend::deallocate(ptr, size) }
}
pub struct CudaHbmBackend;
pub struct CudaGddrBackend;
const _: () = assert!(
core::mem::size_of::<CudaHbmBackend>() == 0
&& core::mem::size_of::<CudaGddrBackend>() == 0
&& core::mem::align_of::<CudaHbmBackend>() == 1
&& core::mem::align_of::<CudaGddrBackend>() == 1
);
impl_device_tier_backend!(CudaHbmBackend);
impl_device_tier_backend!(CudaGddrBackend);