use std::sync::Arc;
use crate::context::Context;
use crate::error::CudaResult;
use crate::event::Event;
use crate::ffi::{CU_STREAM_NON_BLOCKING, CUstream};
use crate::loader::try_driver;
pub struct Stream {
raw: CUstream,
ctx: Arc<Context>,
}
unsafe impl Send for Stream {}
impl Stream {
pub fn new(ctx: &Arc<Context>) -> CudaResult<Self> {
let api = try_driver()?;
let mut raw = CUstream::default();
crate::cuda_call!((api.cu_stream_create)(&mut raw, CU_STREAM_NON_BLOCKING))?;
Ok(Self {
raw,
ctx: Arc::clone(ctx),
})
}
pub fn with_priority(ctx: &Arc<Context>, priority: i32) -> CudaResult<Self> {
let api = try_driver()?;
let mut raw = CUstream::default();
crate::cuda_call!((api.cu_stream_create_with_priority)(
&mut raw,
CU_STREAM_NON_BLOCKING,
priority
))?;
Ok(Self {
raw,
ctx: Arc::clone(ctx),
})
}
pub fn synchronize(&self) -> CudaResult<()> {
let api = try_driver()?;
crate::cuda_call!((api.cu_stream_synchronize)(self.raw))
}
pub fn wait_event(&self, event: &Event) -> CudaResult<()> {
let api = try_driver()?;
crate::cuda_call!((api.cu_stream_wait_event)(self.raw, event.raw(), 0))
}
#[inline]
pub fn raw(&self) -> CUstream {
self.raw
}
#[inline]
pub fn context(&self) -> &Arc<Context> {
&self.ctx
}
}
impl Drop for Stream {
fn drop(&mut self) {
if let Ok(api) = try_driver() {
let rc = unsafe { (api.cu_stream_destroy_v2)(self.raw) };
if rc != 0 {
tracing::warn!(
cuda_error = rc,
stream = ?self.raw,
"cuStreamDestroy_v2 failed during drop"
);
}
}
}
}