use crate::error::CuestError;
use cudarc::driver::{CudaSlice, CudaStream, DevicePtr, SyncOnDrop};
use cuest_ffi::ffi;
use std::sync::Arc;
pub(crate) fn new_descriptor() -> ffi::cuestWorkspaceDescriptor_t {
ffi::cuestWorkspaceDescriptor_t { hostBufferSizeInBytes: 0, deviceBufferSizeInBytes: 0 }
}
pub(crate) struct Workspace {
host: Vec<u64>,
host_bytes: usize,
device: Option<CudaSlice<u8>>,
device_bytes: usize,
}
impl Workspace {
pub(crate) fn new(
stream: &Arc<CudaStream>,
desc: &ffi::cuestWorkspaceDescriptor_t,
) -> Result<Self, CuestError> {
let host_bytes = desc.hostBufferSizeInBytes;
let device_bytes = desc.deviceBufferSizeInBytes;
let host = vec![0u64; host_bytes.div_ceil(8)];
let device = if device_bytes > 0 {
Some(unsafe { stream.alloc::<u8>(device_bytes)? })
} else {
None
};
Ok(Self { host, host_bytes, device, device_bytes })
}
pub(crate) fn raw<'a>(
&'a self,
stream: &'a Arc<CudaStream>,
) -> (ffi::cuestWorkspace_t, Option<SyncOnDrop<'a>>) {
let (device_ptr, guard) = match &self.device {
Some(device) => {
let (ptr, guard) = device.device_ptr(stream);
(ptr as usize, Some(guard))
},
None => (0, None),
};
let host_ptr = if self.host_bytes > 0 { self.host.as_ptr() as usize } else { 0 };
let raw = ffi::cuestWorkspace_t {
hostBuffer: host_ptr,
hostBufferSizeInBytes: self.host_bytes,
deviceBuffer: device_ptr,
deviceBufferSizeInBytes: self.device_bytes,
};
(raw, guard)
}
}