cubecl_core/frontend/
pending.rs1use crate::{self as cubecl, prelude::*};
26use cubecl_ir::{
27 dialect::pending::{CommitOp, ReadyOp, WaitOp},
28 types::pending::{AsyncGroup, WaitUntil},
29};
30use cubecl_macros::{CubeTypeMut, intrinsic};
31use pliron::value::Value;
32
33#[derive(CubeType, CubeTypeMut)]
35#[must_use = "the work runs on until it is waited on"]
36pub struct Pending<T: PendingValue> {
37 #[allow(unused)]
38 pub(crate) value: T,
39 pub(crate) token: GroupToken,
40}
41
42#[cube]
44pub trait PendingValue: CubeType + Sized {
45 fn wait_for(pending: Pending<Self>) -> Self;
47}
48
49#[cube]
50impl<T: PendingValue> Pending<T> {
51 pub fn wait(self) -> T {
53 T::wait_for(self)
54 }
55}
56
57#[cube]
58impl PendingValue for () {
59 fn wait_for(pending: Pending<Self>) -> Self {
60 pending.token.wait();
61 }
62}
63
64#[cube]
65impl Pending<()> {
66 pub fn wait_complete(self) {
70 self.token.wait_until(comptime![WaitUntil::Complete]);
71 }
72}
73
74impl Copy for PendingExpand<()> {}
77impl<T: PendingValue<ExpandType: Clone>> Clone for PendingExpand<T> {
79 fn clone(&self) -> Self {
80 Self {
81 value: self.value.clone(),
82 token: self.token,
83 }
84 }
85}
86impl Copy for Pending<()> {}
87impl<T: PendingValue + Clone> Clone for Pending<T> {
88 fn clone(&self) -> Self {
89 Self {
90 value: self.value.clone(),
91 token: self.token,
92 }
93 }
94}
95
96impl<T: PendingValue> PendingExpand<T> {
97 pub(crate) fn commit(scope: &Scope, group: AsyncGroup, value: T::ExpandType) -> Self {
99 Self {
100 value,
101 token: GroupToken::commit(scope, group),
102 }
103 }
104
105 pub(crate) fn ready(scope: &Scope, group: AsyncGroup, value: T::ExpandType) -> Self {
107 let op = ReadyOp::new(scope.ctx_mut(), group);
108 Self {
109 value,
110 token: scope.register_with_result(&op).into(),
111 }
112 }
113}
114
115#[derive(Clone, Copy)]
117pub(crate) struct GroupToken;
118pub(crate) type GroupTokenExpand = NativeExpand<GroupToken>;
119
120impl GroupToken {
121 pub(crate) fn commit(scope: &Scope, group: AsyncGroup) -> NativeExpand<GroupToken> {
122 let op = CommitOp::new(scope.ctx_mut(), group);
123 scope.register_with_result(&op).into()
124 }
125}
126
127#[cube]
128impl GroupToken {
129 pub(crate) fn wait(&self) {
132 self.wait_until(comptime![WaitUntil::Released]);
133 }
134
135 #[allow(unused_variables)]
137 pub(crate) fn wait_until(&self, #[comptime] until: WaitUntil) {
138 intrinsic!(|scope| {
139 let token = self.read_value(scope);
140 scope.register(&WaitOp::new(scope.ctx_mut(), token, until));
141 })
142 }
143}
144
145impl CubeType for GroupToken {
146 type ExpandType = NativeExpand<GroupToken>;
147}
148
149impl CubeDebug for GroupToken {}
150
151impl ReadValue for NativeExpand<GroupToken> {
152 fn read_value(&self, scope: &Scope) -> Value {
153 self.expand.read_value(scope)
154 }
155}
156
157impl NativeAssign for GroupToken {}
158
159impl AsMutExpand for NativeExpand<GroupToken> {
160 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
161 self
162 }
163}