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