1use std::sync::Arc;
5
6use baracuda_cuda_sys::types::CUevent_flags;
7use baracuda_cuda_sys::{driver, CUevent};
8
9use crate::context::Context;
10use crate::error::{check, Result};
11use crate::stream::Stream;
12
13#[derive(Clone)]
15pub struct Event {
16 inner: Arc<EventInner>,
17}
18
19struct EventInner {
20 handle: CUevent,
21 context: Context,
22}
23
24unsafe impl Send for EventInner {}
26unsafe impl Sync for EventInner {}
27
28impl core::fmt::Debug for EventInner {
29 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
30 f.debug_struct("Event")
31 .field("handle", &self.handle)
32 .finish_non_exhaustive()
33 }
34}
35
36impl core::fmt::Debug for Event {
37 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
38 self.inner.fmt(f)
39 }
40}
41
42impl Event {
43 pub fn new(context: &Context) -> Result<Self> {
45 Self::with_flags(context, CUevent_flags::DEFAULT)
46 }
47
48 pub fn no_timing(context: &Context) -> Result<Self> {
50 Self::with_flags(context, CUevent_flags::DISABLE_TIMING)
51 }
52
53 pub fn with_flags(context: &Context, flags: u32) -> Result<Self> {
55 context.set_current()?;
56 let d = driver()?;
57 let cu = d.cu_event_create()?;
58 let mut event: CUevent = core::ptr::null_mut();
59 check(unsafe { cu(&mut event, flags) })?;
60 Ok(Self {
61 inner: Arc::new(EventInner {
62 handle: event,
63 context: context.clone(),
64 }),
65 })
66 }
67
68 pub fn record(&self, stream: &Stream) -> Result<()> {
71 let d = driver()?;
72 let cu = d.cu_event_record()?;
73 check(unsafe { cu(self.inner.handle, stream.as_raw()) })
74 }
75
76 pub fn record_with_flags(&self, stream: &Stream, flags: u32) -> Result<()> {
79 let d = driver()?;
80 let cu = d.cu_event_record_with_flags()?;
81 check(unsafe { cu(self.inner.handle, stream.as_raw(), flags) })
82 }
83
84 pub fn synchronize(&self) -> Result<()> {
86 let d = driver()?;
87 let cu = d.cu_event_synchronize()?;
88 check(unsafe { cu(self.inner.handle) })
89 }
90
91 pub fn is_complete(&self) -> Result<bool> {
93 use baracuda_cuda_sys::CUresult;
94 let d = driver()?;
95 let cu = d.cu_event_query()?;
96 match unsafe { cu(self.inner.handle) } {
97 CUresult::SUCCESS => Ok(true),
98 CUresult::ERROR_NOT_READY => Ok(false),
99 other => Err(crate::error::Error::Status { status: other }),
100 }
101 }
102
103 pub fn elapsed_time_ms(start: &Event, end: &Event) -> Result<f32> {
107 let d = driver()?;
108 let cu = d.cu_event_elapsed_time()?;
109 let mut ms: f32 = 0.0;
110 check(unsafe { cu(&mut ms, start.inner.handle, end.inner.handle) })?;
111 Ok(ms)
112 }
113
114 #[inline]
116 pub fn context(&self) -> &Context {
117 &self.inner.context
118 }
119
120 #[inline]
122 pub fn as_raw(&self) -> CUevent {
123 self.inner.handle
124 }
125}
126
127impl Drop for EventInner {
128 fn drop(&mut self) {
129 if let Ok(d) = driver() {
130 if let Ok(cu) = d.cu_event_destroy() {
131 let _ = unsafe { cu(self.handle) };
132 }
133 }
134 }
135}