tract_data/tensor/
storage.rs1use std::alloc::Layout;
2use std::fmt;
3use std::hash::Hash;
4
5use crate::TractResult;
6use crate::blob::Blob;
7use crate::datum::DatumType;
8use crate::dyn_eq::DynEq;
9use crate::exotic::ExoticFact;
10use crate::tensor::Tensor;
11use downcast_rs::{Downcast, impl_downcast};
12
13pub trait TensorStorage: Send + Sync + fmt::Debug + fmt::Display + DynEq + Downcast {
21 fn byte_len(&self) -> usize;
22 fn is_empty(&self) -> bool;
23 fn deep_clone(&self) -> Box<dyn TensorStorage>;
24 fn as_plain_ram(&self) -> Option<&PlainStorage>;
25 fn as_plain_ram_mut(&mut self) -> Option<&mut PlainStorage>;
26 fn into_plain_ram(self: Box<Self>) -> Option<PlainStorage>;
27 fn dyn_hash(&self, state: &mut dyn std::hash::Hasher);
28 fn exotic_fact(&self, shape: &[usize]) -> TractResult<Option<Box<dyn ExoticFact>>>;
34
35 fn is_exotic(&self) -> bool {
46 true
47 }
48
49 fn in_ram(&self) -> bool {
56 true
57 }
58
59 fn materialize_plain_ram(&self) -> TractResult<&PlainStorage> {
67 self.as_plain_ram().ok_or_else(|| anyhow::anyhow!("Tensor storage is not plain"))
68 }
69
70 fn slice(
81 &self,
82 _dt: DatumType,
83 _shape: &[usize],
84 _axis: usize,
85 _start: usize,
86 _end: usize,
87 ) -> TractResult<Option<Tensor>> {
88 Ok(None)
89 }
90}
91impl_downcast!(TensorStorage);
92crate::eq_trait_object!(TensorStorage);
93
94#[derive(Eq)]
97pub struct PlainStorage(pub(crate) Blob);
98
99impl PlainStorage {
100 #[inline]
101 pub fn layout(&self) -> &Layout {
102 self.0.layout()
103 }
104
105 #[inline]
106 pub fn as_bytes(&self) -> &[u8] {
107 self.0.as_bytes()
108 }
109
110 #[inline]
111 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
112 self.0.as_bytes_mut()
113 }
114
115 #[inline]
116 pub fn as_ptr(&self) -> *const u8 {
117 self.0.as_bytes().as_ptr()
118 }
119
120 #[inline]
121 pub fn as_mut_ptr(&mut self) -> *mut u8 {
122 self.0.as_bytes_mut().as_mut_ptr()
123 }
124
125 #[inline]
126 pub fn into_blob(self) -> Blob {
127 self.0
128 }
129}
130
131impl Default for PlainStorage {
132 #[inline]
133 fn default() -> Self {
134 PlainStorage(Blob::default())
135 }
136}
137
138impl Clone for PlainStorage {
139 #[inline]
140 fn clone(&self) -> Self {
141 PlainStorage(self.0.clone())
142 }
143}
144
145impl Hash for PlainStorage {
146 #[inline]
147 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
148 self.0.hash(state);
149 }
150}
151
152impl PartialEq for PlainStorage {
153 #[inline]
154 fn eq(&self, other: &Self) -> bool {
155 self.0 == other.0
156 }
157}
158
159impl From<Blob> for PlainStorage {
160 #[inline]
161 fn from(blob: Blob) -> Self {
162 PlainStorage(blob)
163 }
164}
165
166impl std::ops::Deref for PlainStorage {
167 type Target = [u8];
168 #[inline]
169 fn deref(&self) -> &[u8] {
170 self.0.as_bytes()
171 }
172}
173
174impl std::ops::DerefMut for PlainStorage {
175 #[inline]
176 fn deref_mut(&mut self) -> &mut [u8] {
177 self.0.as_bytes_mut()
178 }
179}
180
181impl fmt::Debug for PlainStorage {
182 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183 fmt::Debug::fmt(&self.0, f)
184 }
185}
186
187impl fmt::Display for PlainStorage {
188 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189 fmt::Display::fmt(&self.0, f)
190 }
191}
192
193impl TensorStorage for PlainStorage {
194 #[inline]
195 fn is_empty(&self) -> bool {
196 self.0.is_empty()
197 }
198
199 #[inline]
200 fn byte_len(&self) -> usize {
201 self.0.len()
202 }
203
204 fn deep_clone(&self) -> Box<dyn TensorStorage> {
205 Box::new(PlainStorage(self.0.clone()))
206 }
207
208 fn as_plain_ram(&self) -> Option<&PlainStorage> {
209 Some(self)
210 }
211
212 fn as_plain_ram_mut(&mut self) -> Option<&mut PlainStorage> {
213 Some(self)
214 }
215
216 fn into_plain_ram(self: Box<Self>) -> Option<PlainStorage> {
217 Some(*self)
218 }
219
220 fn dyn_hash(&self, state: &mut dyn std::hash::Hasher) {
221 state.write_u8(0);
222 state.write(self.0.as_bytes());
223 }
224
225 fn exotic_fact(&self, _shape: &[usize]) -> TractResult<Option<Box<dyn ExoticFact>>> {
226 Ok(None)
227 }
228
229 fn is_exotic(&self) -> bool {
230 false
231 }
232}
233
234#[derive(Debug, PartialEq, Eq)]
240#[allow(dead_code)]
241pub(crate) enum StorageKind {
242 Plain(PlainStorage),
243 Exotic(Box<dyn TensorStorage>),
244}
245
246impl StorageKind {
247 #[inline]
248 pub fn as_plain_ram(&self) -> Option<&PlainStorage> {
249 match self {
250 StorageKind::Plain(d) => Some(d),
251 StorageKind::Exotic(o) => o.as_plain_ram(),
252 }
253 }
254
255 #[inline]
256 pub fn as_plain_ram_mut(&mut self) -> Option<&mut PlainStorage> {
257 match self {
258 StorageKind::Plain(d) => Some(d),
259 StorageKind::Exotic(o) => o.as_plain_ram_mut(),
260 }
261 }
262
263 #[inline]
264 pub fn into_plain_ram(self) -> Option<PlainStorage> {
265 match self {
266 StorageKind::Plain(d) => Some(d),
267 StorageKind::Exotic(o) => o.into_plain_ram(),
268 }
269 }
270
271 #[inline]
272 pub fn byte_len(&self) -> usize {
273 match self {
274 StorageKind::Plain(d) => d.0.len(),
275 StorageKind::Exotic(o) => o.byte_len(),
276 }
277 }
278
279 #[inline]
280 pub fn is_empty(&self) -> bool {
281 match self {
282 StorageKind::Plain(d) => d.0.is_empty(),
283 StorageKind::Exotic(o) => o.is_empty(),
284 }
285 }
286
287 #[inline]
288 #[allow(dead_code)]
289 pub fn deep_clone(&self) -> StorageKind {
290 match self {
291 StorageKind::Plain(d) => StorageKind::Plain(d.clone()),
292 StorageKind::Exotic(o) => StorageKind::Exotic(o.deep_clone()),
293 }
294 }
295
296 #[inline]
297 pub fn is_exotic(&self) -> bool {
298 match self {
299 StorageKind::Plain(_) => false,
300 StorageKind::Exotic(o) => o.is_exotic(),
301 }
302 }
303
304 #[inline]
305 pub fn in_ram(&self) -> bool {
306 match self {
307 StorageKind::Plain(_) => true,
308 StorageKind::Exotic(o) => o.in_ram(),
309 }
310 }
311
312 #[inline]
313 pub fn materialize_plain_ram(&self) -> TractResult<&PlainStorage> {
314 match self {
315 StorageKind::Plain(d) => Ok(d),
316 StorageKind::Exotic(o) => o.materialize_plain_ram(),
317 }
318 }
319
320 #[inline]
321 pub fn as_storage(&self) -> &dyn TensorStorage {
322 match self {
323 StorageKind::Plain(d) => d,
324 StorageKind::Exotic(o) => o.as_ref(),
325 }
326 }
327
328 #[inline]
329 #[allow(dead_code)]
330 pub fn as_storage_mut(&mut self) -> &mut dyn TensorStorage {
331 match self {
332 StorageKind::Plain(d) => d,
333 StorageKind::Exotic(o) => o.as_mut(),
334 }
335 }
336
337 pub fn dyn_hash(&self, state: &mut dyn std::hash::Hasher) {
338 match self {
339 StorageKind::Plain(d) => {
340 state.write_u8(0);
341 state.write(d.as_bytes())
342 }
343 StorageKind::Exotic(o) => o.dyn_hash(state),
344 }
345 }
346}