use core::ffi::c_void;
use baracuda_cuda_sys::runtime::runtime;
use baracuda_cuda_sys::runtime::types::{cudaExtent, cudaMemcpy3DParms, cudaPitchedPtr};
use baracuda_types::DeviceRepr;
use crate::error::{check, Result};
use crate::stream::Stream;
pub struct Pitched3dBuffer<T: DeviceRepr> {
ptr: cudaPitchedPtr,
extent: cudaExtent,
_marker: core::marker::PhantomData<T>,
}
impl<T: DeviceRepr> core::fmt::Debug for Pitched3dBuffer<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Pitched3dBuffer")
.field("ptr", &self.ptr.ptr)
.field("pitch", &self.ptr.pitch)
.field("extent", &self.extent)
.finish()
}
}
impl<T: DeviceRepr> Pitched3dBuffer<T> {
pub fn new(width: usize, height: usize, depth: usize) -> Result<Self> {
let r = runtime()?;
let cu = r.cuda_malloc_3d()?;
let extent = cudaExtent {
width: width * core::mem::size_of::<T>(),
height,
depth,
};
let mut pitched = cudaPitchedPtr::default();
check(unsafe {
cu(
&mut pitched as *mut cudaPitchedPtr as *mut c_void,
&extent as *const cudaExtent as *const c_void,
)
})?;
Ok(Self {
ptr: pitched,
extent,
_marker: core::marker::PhantomData,
})
}
#[inline]
pub fn as_pitched_ptr(&self) -> cudaPitchedPtr {
self.ptr
}
#[inline]
pub fn extent(&self) -> cudaExtent {
self.extent
}
#[inline]
pub fn pitch_bytes(&self) -> usize {
self.ptr.pitch
}
}
impl<T: DeviceRepr> Drop for Pitched3dBuffer<T> {
fn drop(&mut self) {
if self.ptr.ptr.is_null() {
return;
}
if let Ok(r) = runtime() {
if let Ok(cu) = r.cuda_free() {
let _ = unsafe { cu(self.ptr.ptr) };
}
}
}
}
pub unsafe fn memcpy_3d(params: &cudaMemcpy3DParms) -> Result<()> { unsafe {
let r = runtime()?;
let cu = r.cuda_memcpy_3d()?;
check(cu(params as *const cudaMemcpy3DParms as *const c_void))
}}
pub unsafe fn memcpy_3d_async(params: &cudaMemcpy3DParms, stream: &Stream) -> Result<()> { unsafe {
let r = runtime()?;
let cu = r.cuda_memcpy_3d_async()?;
check(cu(
params as *const cudaMemcpy3DParms as *const c_void,
stream.as_raw(),
))
}}
pub unsafe fn memcpy_3d_peer(params: &cudaMemcpy3DParms) -> Result<()> { unsafe {
let r = runtime()?;
let cu = r.cuda_memcpy_3d_peer()?;
check(cu(params as *const cudaMemcpy3DParms as *const c_void))
}}
pub unsafe fn memcpy_3d_peer_async(params: &cudaMemcpy3DParms, stream: &Stream) -> Result<()> { unsafe {
let r = runtime()?;
let cu = r.cuda_memcpy_3d_peer_async()?;
check(cu(
params as *const cudaMemcpy3DParms as *const c_void,
stream.as_raw(),
))
}}
pub unsafe fn memset_3d(pitched: cudaPitchedPtr, value: i32, extent: cudaExtent) -> Result<()> { unsafe {
let r = runtime()?;
let cu = r.cuda_memset_3d()?;
let mut p = pitched;
check(cu(
&mut p as *mut cudaPitchedPtr as *mut c_void,
value,
&extent as *const cudaExtent as *const c_void,
))
}}