1use cubecl_common::device::ServiceId;
2use cubecl_environment::stream::StreamId;
3use cubecl_zspace::{Shape, Strides};
4
5use crate::{
6 memory_management::{
7 ManagedMemoryBinding, ManagedMemoryHandle, ManagedMemoryId, WeakMemoryBinding,
8 },
9 server::{CopyDescriptor, TensorMapBinding},
10};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum Overlap {
15 Disjoint,
17 Same,
19 Partial,
21}
22
23pub struct Handle {
25 pub memory: ManagedMemoryHandle,
27 pub service: ServiceId,
32 pub offset_start: Option<u64>,
34 pub offset_end: Option<u64>,
36 pub stream: StreamId,
38 pub(crate) size: u64,
40}
41
42impl core::fmt::Debug for Handle {
43 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
44 f.debug_struct("Handle")
45 .field("id", &self.memory)
46 .field("service", &self.service)
47 .field("offset_start", &self.offset_start)
48 .field("offset_end", &self.offset_end)
49 .field("stream", &self.stream)
50 .field("size", &self.size)
51 .finish()
52 }
53}
54
55impl Clone for Handle {
56 fn clone(&self) -> Self {
57 Self {
58 memory: self.memory.clone(),
59 service: self.service,
60 offset_start: self.offset_start,
61 offset_end: self.offset_end,
62 stream: self.stream,
63 size: self.size,
64 }
65 }
66}
67
68impl Handle {
69 pub fn from_memory(
71 id: ManagedMemoryHandle,
72 service: ServiceId,
73 stream: StreamId,
74 size: u64,
75 ) -> Self {
76 Self {
77 memory: id,
78 service,
79 offset_start: None,
80 offset_end: None,
81 stream,
82 size,
83 }
84 }
85 pub fn new(service: ServiceId, stream: StreamId, size: u64) -> Self {
87 Self {
88 memory: ManagedMemoryHandle::new(),
89 service,
90 offset_start: None,
91 offset_end: None,
92 stream,
93 size,
94 }
95 }
96 pub fn can_mut(&self) -> bool {
98 self.memory.can_mut()
99 }
100
101 pub fn binding(self) -> BufferBinding {
103 BufferBinding {
104 memory: self.memory.binding(),
105 service: self.service,
106 offset_start: self.offset_start,
107 offset_end: self.offset_end,
108 stream: self.stream,
109 size: self.size,
110 }
111 }
112
113 pub fn offset_start(mut self, offset: u64) -> Self {
115 if let Some(val) = &mut self.offset_start {
116 *val += offset;
117 } else {
118 self.offset_start = Some(offset);
119 }
120
121 self
122 }
123 pub fn offset_end(mut self, offset: u64) -> Self {
125 if let Some(val) = &mut self.offset_end {
126 *val += offset;
127 } else {
128 self.offset_end = Some(offset);
129 }
130
131 self
132 }
133
134 pub fn copy_descriptor(
136 self,
137 shape: Shape,
138 strides: Strides,
139 elem_size: usize,
140 ) -> CopyDescriptor {
141 CopyDescriptor {
142 shape,
143 strides,
144 elem_size,
145 handle: self.binding(),
146 }
147 }
148 pub fn overlap(&self, other: &Self) -> Overlap {
150 let bytes = |handle: &Self| {
151 handle.offset_start.unwrap_or(0)..handle.size - handle.offset_end.unwrap_or(0)
152 };
153 let mine = bytes(self);
154 let theirs = bytes(other);
155 if self.memory.descriptor().id != other.memory.descriptor().id
156 || mine.end <= theirs.start
157 || theirs.end <= mine.start
158 {
159 Overlap::Disjoint
160 } else if mine == theirs {
161 Overlap::Same
162 } else {
163 Overlap::Partial
164 }
165 }
166 pub fn size_in_used(&self) -> u64 {
168 self.size - self.offset_start.unwrap_or(0) - self.offset_end.unwrap_or(0)
169 }
170 pub fn size(&self) -> u64 {
172 self.size
173 }
174}
175
176#[allow(clippy::large_enum_variant)]
178#[derive(Clone, Debug)]
179pub enum KernelResource {
180 Buffer(BufferBinding),
182 TensorMap(TensorMapBinding),
184}
185
186#[derive(Clone, Debug)]
195pub struct BufferBinding {
196 pub memory: ManagedMemoryBinding,
198 pub service: ServiceId,
200 pub offset_start: Option<u64>,
202 pub offset_end: Option<u64>,
204 pub stream: StreamId,
206 pub size: u64,
208}
209
210#[derive(Clone, Debug)]
214pub struct WeakBufferBinding {
215 memory: WeakMemoryBinding,
216 service: ServiceId,
217 offset_start: Option<u64>,
218 offset_end: Option<u64>,
219 stream: StreamId,
220 size: u64,
221}
222
223impl WeakBufferBinding {
224 pub fn upgrade(&self) -> Option<BufferBinding> {
227 Some(BufferBinding {
228 memory: self.memory.upgrade()?,
229 service: self.service,
230 offset_start: self.offset_start,
231 offset_end: self.offset_end,
232 stream: self.stream,
233 size: self.size,
234 })
235 }
236}
237
238impl BufferBinding {
239 pub fn downgrade(&self) -> WeakBufferBinding {
241 WeakBufferBinding {
242 memory: self.memory.downgrade(),
243 service: self.service,
244 offset_start: self.offset_start,
245 offset_end: self.offset_end,
246 stream: self.stream,
247 size: self.size,
248 }
249 }
250
251 pub fn size_in_used(&self) -> u64 {
253 self.size - self.offset_start.unwrap_or(0) - self.offset_end.unwrap_or(0)
254 }
255
256 pub fn range(&self) -> core::ops::Range<u64> {
261 self.offset_start.unwrap_or(0)..self.size - self.offset_end.unwrap_or(0)
262 }
263
264 pub fn claim_key(&self) -> (ManagedMemoryId, u64, u64) {
273 let range = self.range();
274 (self.memory.id(), range.start, range.end)
275 }
276 pub fn size(&self) -> u64 {
278 self.size
279 }
280}