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
12pub struct Handle {
14 pub memory: ManagedMemoryHandle,
16 pub service: ServiceId,
21 pub offset_start: Option<u64>,
23 pub offset_end: Option<u64>,
25 pub stream: StreamId,
27 pub(crate) size: u64,
29}
30
31impl core::fmt::Debug for Handle {
32 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33 f.debug_struct("Handle")
34 .field("id", &self.memory)
35 .field("service", &self.service)
36 .field("offset_start", &self.offset_start)
37 .field("offset_end", &self.offset_end)
38 .field("stream", &self.stream)
39 .field("size", &self.size)
40 .finish()
41 }
42}
43
44impl Clone for Handle {
45 fn clone(&self) -> Self {
46 Self {
47 memory: self.memory.clone(),
48 service: self.service,
49 offset_start: self.offset_start,
50 offset_end: self.offset_end,
51 stream: self.stream,
52 size: self.size,
53 }
54 }
55}
56
57impl Handle {
58 pub fn from_memory(
60 id: ManagedMemoryHandle,
61 service: ServiceId,
62 stream: StreamId,
63 size: u64,
64 ) -> Self {
65 Self {
66 memory: id,
67 service,
68 offset_start: None,
69 offset_end: None,
70 stream,
71 size,
72 }
73 }
74 pub fn new(service: ServiceId, stream: StreamId, size: u64) -> Self {
76 Self {
77 memory: ManagedMemoryHandle::new(),
78 service,
79 offset_start: None,
80 offset_end: None,
81 stream,
82 size,
83 }
84 }
85 pub fn can_mut(&self) -> bool {
87 self.memory.can_mut()
88 }
89
90 pub fn binding(self) -> BufferBinding {
92 BufferBinding {
93 memory: self.memory.binding(),
94 service: self.service,
95 offset_start: self.offset_start,
96 offset_end: self.offset_end,
97 stream: self.stream,
98 size: self.size,
99 }
100 }
101
102 pub fn offset_start(mut self, offset: u64) -> Self {
104 if let Some(val) = &mut self.offset_start {
105 *val += offset;
106 } else {
107 self.offset_start = Some(offset);
108 }
109
110 self
111 }
112 pub fn offset_end(mut self, offset: u64) -> Self {
114 if let Some(val) = &mut self.offset_end {
115 *val += offset;
116 } else {
117 self.offset_end = Some(offset);
118 }
119
120 self
121 }
122
123 pub fn copy_descriptor(
125 self,
126 shape: Shape,
127 strides: Strides,
128 elem_size: usize,
129 ) -> CopyDescriptor {
130 CopyDescriptor {
131 shape,
132 strides,
133 elem_size,
134 handle: self.binding(),
135 }
136 }
137 pub fn size_in_used(&self) -> u64 {
139 self.size - self.offset_start.unwrap_or(0) - self.offset_end.unwrap_or(0)
140 }
141 pub fn size(&self) -> u64 {
143 self.size
144 }
145}
146
147#[allow(clippy::large_enum_variant)]
149#[derive(Clone, Debug)]
150pub enum KernelResource {
151 Buffer(BufferBinding),
153 TensorMap(TensorMapBinding),
155}
156
157#[derive(Clone, Debug)]
166pub struct BufferBinding {
167 pub memory: ManagedMemoryBinding,
169 pub service: ServiceId,
171 pub offset_start: Option<u64>,
173 pub offset_end: Option<u64>,
175 pub stream: StreamId,
177 pub size: u64,
179}
180
181#[derive(Clone, Debug)]
185pub struct WeakBufferBinding {
186 memory: WeakMemoryBinding,
187 service: ServiceId,
188 offset_start: Option<u64>,
189 offset_end: Option<u64>,
190 stream: StreamId,
191 size: u64,
192}
193
194impl WeakBufferBinding {
195 pub fn upgrade(&self) -> Option<BufferBinding> {
198 Some(BufferBinding {
199 memory: self.memory.upgrade()?,
200 service: self.service,
201 offset_start: self.offset_start,
202 offset_end: self.offset_end,
203 stream: self.stream,
204 size: self.size,
205 })
206 }
207}
208
209impl BufferBinding {
210 pub fn downgrade(&self) -> WeakBufferBinding {
212 WeakBufferBinding {
213 memory: self.memory.downgrade(),
214 service: self.service,
215 offset_start: self.offset_start,
216 offset_end: self.offset_end,
217 stream: self.stream,
218 size: self.size,
219 }
220 }
221
222 pub fn size_in_used(&self) -> u64 {
224 self.size - self.offset_start.unwrap_or(0) - self.offset_end.unwrap_or(0)
225 }
226
227 pub fn range(&self) -> core::ops::Range<u64> {
232 self.offset_start.unwrap_or(0)..self.size - self.offset_end.unwrap_or(0)
233 }
234
235 pub fn claim_key(&self) -> (ManagedMemoryId, u64, u64) {
244 let range = self.range();
245 (self.memory.id(), range.start, range.end)
246 }
247 pub fn size(&self) -> u64 {
249 self.size
250 }
251}