cubecl_server/device_events/
event.rs1use alloc::vec::Vec;
2use core::ops::Deref;
3
4use cubecl_environment::sync::{Arc, Mutex};
5
6use crate::device_events::EventApi;
7use crate::driver::DriverError;
8
9pub struct Event<A: EventApi> {
12 sys: A::Event,
13}
14
15impl<A: EventApi> Event<A> {
16 pub fn new() -> Result<Self, DriverError> {
22 Ok(Self {
23 sys: A::event_create()?,
24 })
25 }
26
27 pub fn record(&self, stream: A::Stream) -> Result<(), DriverError> {
33 A::event_record(&self.sys, stream)
34 }
35
36 pub fn wait(&self) -> Result<(), DriverError> {
42 A::event_wait(&self.sys)
43 }
44
45 pub fn wait_async(&self, stream: A::Stream) -> Result<(), DriverError> {
51 A::stream_wait_event(stream, &self.sys)
52 }
53
54 pub fn elapsed(&self, other: &Self) -> Result<cubecl_common::profile::Duration, DriverError> {
61 A::event_elapsed(&self.sys, &other.sys)
62 }
63}
64
65impl<A: EventApi> Drop for Event<A> {
66 fn drop(&mut self) {
67 if let Err(err) = A::event_destroy(&mut self.sys) {
68 log::warn!("Failed to release a {} event: {err}", A::BACKEND);
69 }
70 }
71}
72
73impl<A: EventApi> core::fmt::Debug for Event<A> {
74 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
75 write!(f, "{}Event", A::BACKEND)
76 }
77}
78
79pub(crate) struct EventPool<A: EventApi> {
87 free: Arc<Mutex<Vec<Event<A>>>>,
88}
89
90impl<A: EventApi> EventPool<A> {
91 pub(crate) fn acquire(&self) -> Result<Pooled<A>, DriverError> {
101 let event = match self.free.lock().pop() {
102 Some(event) => event,
103 None => Event::new()?,
104 };
105
106 Ok(Pooled {
107 event: Some(event),
108 pool: self.clone(),
109 })
110 }
111
112 fn release(&self, event: Event<A>) {
113 self.free.lock().push(event);
114 }
115}
116
117impl<A: EventApi> Clone for EventPool<A> {
118 fn clone(&self) -> Self {
119 Self {
120 free: self.free.clone(),
121 }
122 }
123}
124
125impl<A: EventApi> Default for EventPool<A> {
126 fn default() -> Self {
127 Self {
128 free: Arc::new(Mutex::new(Vec::new())),
129 }
130 }
131}
132
133impl<A: EventApi> core::fmt::Debug for EventPool<A> {
134 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
135 write!(f, "EventPool<{}>({})", A::BACKEND, self.free.lock().len())
136 }
137}
138
139pub(crate) struct Pooled<A: EventApi> {
146 event: Option<Event<A>>,
149 pool: EventPool<A>,
150}
151
152impl<A: EventApi> Deref for Pooled<A> {
153 type Target = Event<A>;
154
155 fn deref(&self) -> &Self::Target {
156 self.event.as_ref().expect("emptied only by Drop")
157 }
158}
159
160impl<A: EventApi> Drop for Pooled<A> {
161 fn drop(&mut self) {
162 if let Some(event) = self.event.take() {
163 self.pool.release(event);
164 }
165 }
166}
167
168impl<A: EventApi> core::fmt::Debug for Pooled<A> {
169 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
170 write!(f, "Pooled<{}>", A::BACKEND)
171 }
172}