1use crate::{AnyTensorRef, Device, TensorRef, prelude::*};
2use mnn_sys::HalideType;
3
4#[repr(transparent)]
10pub struct TensorList<'t> {
11 pub(crate) inner: *const mnn_sys::TensorInfoArray,
12 pub(crate) __marker: PhantomData<&'t ()>,
13}
14
15impl core::fmt::Debug for TensorList<'_> {
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> core::fmt::Result {
17 f.debug_list().entries(self.iter()).finish()
18 }
19}
20
21impl Drop for TensorList<'_> {
22 fn drop(&mut self) {
23 unsafe { mnn_sys::destroyTensorInfoArray(self.inner.cast_mut()) }
24 }
25}
26
27impl<'t> TensorList<'t> {
28 pub(crate) fn from_ptr(inner: *const mnn_sys::TensorInfoArray) -> Self {
29 Self {
30 inner,
31 __marker: PhantomData,
32 }
33 }
34
35 pub fn size(&self) -> usize {
37 unsafe { (*self.inner).size }
38 }
39
40 pub fn get(&self, index: usize) -> Option<TensorInfo<'t, '_>> {
42 if index >= self.size() {
43 None
44 } else {
45 let gtinfo = unsafe { mnn_sys::getTensorInfoArray(self.inner, index) };
46 if !gtinfo.is_null() {
47 Some(TensorInfo {
48 tensor_info: gtinfo,
49 __marker: PhantomData,
50 })
51 } else {
52 None
53 }
54 }
55 }
56
57 pub fn iter<'tl>(&'tl self) -> TensorListIter<'t, 'tl> {
59 TensorListIter {
60 tensor_list: self,
61 idx: 0,
62 }
63 }
64}
65
66impl<'t, 'tl> IntoIterator for &'tl TensorList<'t> {
67 type Item = TensorInfo<'t, 'tl>;
68 type IntoIter = TensorListIter<'t, 'tl>;
69
70 fn into_iter(self) -> Self::IntoIter {
71 self.iter()
72 }
73}
74
75#[repr(transparent)]
81pub struct TensorListMut<'t> {
82 inner: TensorList<'t>,
83}
84
85impl core::fmt::Debug for TensorListMut<'_> {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> core::fmt::Result {
87 self.inner.fmt(f)
88 }
89}
90
91impl<'t> core::ops::Deref for TensorListMut<'t> {
92 type Target = TensorList<'t>;
93
94 fn deref(&self) -> &Self::Target {
95 &self.inner
96 }
97}
98
99impl<'t> TensorListMut<'t> {
100 pub(crate) fn from_ptr(inner: *const mnn_sys::TensorInfoArray) -> Self {
101 Self {
102 inner: TensorList::from_ptr(inner),
103 }
104 }
105
106 pub fn get_mut(&mut self, index: usize) -> Option<TensorInfoMut<'t, '_>> {
108 if index >= self.inner.size() {
109 None
110 } else {
111 let gtinfo = unsafe { mnn_sys::getTensorInfoArray(self.inner.inner, index) };
112 if !gtinfo.is_null() {
113 Some(TensorInfoMut {
114 tensor_info: gtinfo,
115 __marker: PhantomData,
116 })
117 } else {
118 None
119 }
120 }
121 }
122
123 pub fn iter_mut<'tl>(&'tl mut self) -> TensorListIterMut<'t, 'tl> {
125 TensorListIterMut {
126 tensor_list: self,
127 idx: 0,
128 }
129 }
130}
131
132impl<'t, 'tl> IntoIterator for &'tl TensorListMut<'t> {
133 type Item = TensorInfo<'t, 'tl>;
134 type IntoIter = TensorListIter<'t, 'tl>;
135
136 fn into_iter(self) -> Self::IntoIter {
137 self.inner.iter()
138 }
139}
140
141impl<'t, 'tl> IntoIterator for &'tl mut TensorListMut<'t> {
142 type Item = TensorInfoMut<'t, 'tl>;
143 type IntoIter = TensorListIterMut<'t, 'tl>;
144
145 fn into_iter(self) -> Self::IntoIter {
146 self.iter_mut()
147 }
148}
149
150pub struct TensorListIter<'t, 'tl> {
152 tensor_list: &'tl TensorList<'t>,
153 idx: usize,
154}
155
156impl<'t, 'tl> Iterator for TensorListIter<'t, 'tl> {
157 type Item = TensorInfo<'t, 'tl>;
158 fn next(&mut self) -> Option<Self::Item> {
159 let idx = self.idx;
160 self.idx += 1;
161 self.tensor_list.get(idx)
162 }
163}
164
165pub struct TensorListIterMut<'t, 'tl> {
167 tensor_list: &'tl mut TensorListMut<'t>,
168 idx: usize,
169}
170
171impl<'t, 'tl> Iterator for TensorListIterMut<'t, 'tl> {
172 type Item = TensorInfoMut<'t, 'tl>;
173 fn next(&mut self) -> Option<Self::Item> {
174 let idx = self.idx;
175 self.idx += 1;
176 let out = self.tensor_list.get_mut(idx);
177 unsafe {
183 core::mem::transmute::<Option<TensorInfoMut<'t, '_>>, Option<TensorInfoMut<'t, 'tl>>>(
184 out,
185 )
186 }
187 }
188}
189
190#[repr(transparent)]
192pub struct TensorInfo<'t, 'tl> {
193 pub(crate) tensor_info: *mut mnn_sys::TensorInfo,
194 pub(crate) __marker: PhantomData<&'tl TensorList<'t>>,
195}
196
197impl core::fmt::Debug for TensorInfo<'_, '_> {
198 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
199 let tensor = self.raw_tensor();
200 let shape = tensor.shape();
201 f.debug_struct("TensorInfo")
202 .field("name", &self.name())
203 .field("tensor", &shape)
204 .finish()
205 }
206}
207
208#[repr(transparent)]
213pub struct TensorInfoMut<'t, 'tl> {
214 pub(crate) tensor_info: *mut mnn_sys::TensorInfo,
215 pub(crate) __marker: PhantomData<&'tl mut TensorList<'t>>,
216}
217
218impl core::fmt::Debug for TensorInfoMut<'_, '_> {
219 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
220 let tensor = self.raw_tensor();
221 let shape = tensor.shape();
222 f.debug_struct("TensorInfoMut")
223 .field("name", &self.name())
224 .field("tensor", &shape)
225 .finish()
226 }
227}
228
229fn check_tensor<H: HalideType>(tensor: &AnyTensorRef) -> Result<()> {
231 ensure!(!tensor.is_dynamic_unsized(), ErrorKind::DynamicTensorError);
232 ensure!(
233 tensor.is_type_of::<H>(),
234 ErrorKind::HalideTypeMismatch {
235 got: std::any::type_name::<H>(),
236 }
237 );
238 Ok(())
239}
240
241impl<'t, 'tl> TensorInfoMut<'t, 'tl> {
242 fn tensor_ptr(&self) -> *mut mnn_sys::Tensor {
243 debug_assert!(!self.tensor_info.is_null());
244 let tensor = unsafe { (*self.tensor_info).tensor };
245 debug_assert!(!tensor.is_null());
246 tensor.cast()
247 }
248
249 pub fn name(&self) -> &'tl str {
251 debug_assert!(!self.tensor_info.is_null());
252 unsafe { (*self.tensor_info).name.to_cstr() }
253 .to_str()
254 .expect("Tensor name is not utf-8")
255 }
256
257 pub fn tensor<H: HalideType>(&self) -> Result<&TensorRef<H, Device>> {
259 check_tensor::<H>(self.raw_tensor())?;
260 Ok(unsafe { crate::tensor::from_raw_parts(self.tensor_ptr()) })
261 }
262
263 pub fn tensor_mut<H: HalideType>(&mut self) -> Result<&mut TensorRef<H, Device>> {
268 check_tensor::<H>(self.raw_tensor())?;
269 Ok(unsafe { crate::tensor::from_raw_parts_mut(self.tensor_ptr()) })
270 }
271
272 pub fn into_tensor_mut<H: HalideType>(self) -> Result<&'tl mut TensorRef<H, Device>> {
275 check_tensor::<H>(self.raw_tensor())?;
276 Ok(unsafe { crate::tensor::from_raw_parts_mut(self.tensor_ptr()) })
279 }
280
281 pub unsafe fn tensor_unresized<H: HalideType>(&mut self) -> Result<&mut TensorRef<H, Device>> {
284 let tensor = self.raw_tensor();
285 ensure!(
286 tensor.is_type_of::<H>(),
287 ErrorKind::HalideTypeMismatch {
288 got: std::any::type_name::<H>(),
289 }
290 );
291 Ok(unsafe { crate::tensor::from_raw_parts_mut(self.tensor_ptr()) })
292 }
293
294 pub fn raw_tensor(&self) -> &AnyTensorRef {
296 unsafe { AnyTensorRef::from_ptr(self.tensor_ptr()) }
297 }
298
299 pub fn raw_tensor_mut(&mut self) -> &mut AnyTensorRef {
301 unsafe { AnyTensorRef::from_mut_ptr(self.tensor_ptr()) }
302 }
303}
304
305impl<'t, 'tl> TensorInfo<'t, 'tl> {
306 fn tensor_ptr(&self) -> *mut mnn_sys::Tensor {
307 debug_assert!(!self.tensor_info.is_null());
308 let tensor = unsafe { (*self.tensor_info).tensor };
309 debug_assert!(!tensor.is_null());
310 tensor.cast()
311 }
312
313 pub fn name(&self) -> &'tl str {
315 debug_assert!(!self.tensor_info.is_null());
316 unsafe { (*self.tensor_info).name.to_cstr() }
317 .to_str()
318 .expect("Tensor name is not utf-8")
319 }
320
321 pub fn tensor<H: HalideType>(&self) -> Result<&'tl TensorRef<H, Device>> {
323 check_tensor::<H>(self.raw_tensor())?;
324 Ok(unsafe { crate::tensor::from_raw_parts(self.tensor_ptr()) })
325 }
326
327 pub fn raw_tensor(&self) -> &'tl AnyTensorRef {
329 unsafe { AnyTensorRef::from_ptr(self.tensor_ptr()) }
330 }
331}