use baracuda_cuda_sys::driver;
use baracuda_cuda_sys::types::CUpointer_attribute;
use baracuda_cuda_sys::CUdeviceptr;
use crate::error::{check, Result};
pub unsafe fn raw_attribute(
attribute: i32,
ptr: CUdeviceptr,
out: *mut core::ffi::c_void,
) -> Result<()> { unsafe {
let d = driver()?;
let cu = d.cu_pointer_get_attribute()?;
check(cu(out, attribute, ptr))
}}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum MemoryType {
Host,
Device,
Array,
Unified,
Unknown(u32),
}
impl MemoryType {
#[inline]
fn from_raw(raw: u32) -> Self {
use baracuda_cuda_sys::types::CUmemorytype;
match raw {
CUmemorytype::HOST => MemoryType::Host,
CUmemorytype::DEVICE => MemoryType::Device,
CUmemorytype::ARRAY => MemoryType::Array,
CUmemorytype::UNIFIED => MemoryType::Unified,
other => MemoryType::Unknown(other),
}
}
}
pub fn memory_type(ptr: CUdeviceptr) -> Result<MemoryType> {
let mut raw: u32 = 0;
unsafe {
raw_attribute(
CUpointer_attribute::MEMORY_TYPE,
ptr,
&mut raw as *mut u32 as *mut core::ffi::c_void,
)?;
}
Ok(MemoryType::from_raw(raw))
}
pub fn is_managed(ptr: CUdeviceptr) -> Result<bool> {
let mut raw: u32 = 0;
unsafe {
raw_attribute(
CUpointer_attribute::IS_MANAGED,
ptr,
&mut raw as *mut u32 as *mut core::ffi::c_void,
)?;
}
Ok(raw != 0)
}
pub fn device_ordinal(ptr: CUdeviceptr) -> Result<i32> {
let mut raw: i32 = 0;
unsafe {
raw_attribute(
CUpointer_attribute::DEVICE_ORDINAL,
ptr,
&mut raw as *mut i32 as *mut core::ffi::c_void,
)?;
}
Ok(raw)
}
pub fn range_size(ptr: CUdeviceptr) -> Result<usize> {
let mut raw: usize = 0;
unsafe {
raw_attribute(
CUpointer_attribute::RANGE_SIZE,
ptr,
&mut raw as *mut usize as *mut core::ffi::c_void,
)?;
}
Ok(raw)
}
pub unsafe fn raw_attributes_batched(
attributes: &mut [i32],
data: &mut [*mut core::ffi::c_void],
ptr: CUdeviceptr,
) -> Result<()> { unsafe {
assert_eq!(
attributes.len(),
data.len(),
"attributes / data length mismatch"
);
let d = driver()?;
let cu = d.cu_pointer_get_attributes()?;
check(cu(
attributes.len() as core::ffi::c_uint,
attributes.as_mut_ptr(),
data.as_mut_ptr(),
ptr,
))
}}
pub unsafe fn range_attribute_raw(
attribute: i32,
ptr: CUdeviceptr,
count: usize,
out: *mut core::ffi::c_void,
data_size: usize,
) -> Result<()> { unsafe {
let d = driver()?;
let cu = d.cu_mem_range_get_attribute()?;
check(cu(out, data_size, attribute, ptr, count))
}}
pub unsafe fn range_attributes_batched(
attributes: &mut [i32],
data: &mut [*mut core::ffi::c_void],
data_sizes: &mut [usize],
ptr: CUdeviceptr,
count: usize,
) -> Result<()> { unsafe {
assert_eq!(attributes.len(), data.len());
assert_eq!(attributes.len(), data_sizes.len());
let d = driver()?;
let cu = d.cu_mem_range_get_attributes()?;
check(cu(
data.as_mut_ptr(),
data_sizes.as_mut_ptr(),
attributes.as_mut_ptr(),
attributes.len(),
ptr,
count,
))
}}
pub unsafe fn set_attribute_raw(
value: *const core::ffi::c_void,
attribute: i32,
ptr: CUdeviceptr,
) -> Result<()> { unsafe {
let d = driver()?;
let cu = d.cu_pointer_set_attribute()?;
check(cu(value, attribute, ptr))
}}