@@ -190,12 +190,15 @@ where
190190/* ndarray => DLPack */
191191/*****************************************************************************/
192192
193- fn array_to_tensor_view < T , D > ( array : ndarray:: ArrayView < ' _ , T , D > ) -> Result < sys:: DLTensor , DLPackNDarrayError > where
193+ fn array_to_tensor_view < ' a , S , D , T > ( array : & ' a ndarray:: ArrayBase < S , D > ) -> Result < sys:: DLTensor , DLPackNDarrayError > where
194194 D : ndarray:: Dimension ,
195+ S : ndarray:: RawData < Elem = T > ,
195196 T : GetDLPackDataType ,
196197{
197- let shape = array. shape ( ) ;
198- let strides = ndarray:: ArrayView :: strides ( & array) ;
198+ // SAFETY: we make sure that shape and strides are valid for the lifetime of
199+ // the array
200+ let shape: & ' a [ _ ] = array. shape ( ) ;
201+ let strides: & ' a [ _ ] = ndarray:: ArrayBase :: strides ( array) ;
199202
200203 // we need a `*const i64` for DLTensor, but we have usize and isize.
201204 // on 64-bit targets, isize will be the same as i64, so that's fine.
@@ -212,7 +215,6 @@ fn array_to_tensor_view<T, D>(array: ndarray::ArrayView<'_, T, D>) -> Result<sys
212215 let ndim = shape. len ( ) as i32 ;
213216 let shape = shape. as_ptr ( ) . cast_mut ( ) . cast :: < i64 > ( ) ;
214217
215-
216218 let device = sys:: DLDevice {
217219 device_type : sys:: DLDeviceType :: kDLCPU,
218220 device_id : 0 ,
@@ -229,13 +231,13 @@ fn array_to_tensor_view<T, D>(array: ndarray::ArrayView<'_, T, D>) -> Result<sys
229231 } ) ;
230232}
231233
232- impl < ' a , T , D > TryFrom < ndarray:: ArrayView < ' a , T , D > > for DLPackTensorRef < ' a > where
234+ impl < ' a , T , D > TryFrom < & ' a ndarray:: ArrayView < ' a , T , D > > for DLPackTensorRef < ' a > where
233235 D : ndarray:: Dimension ,
234236 T : GetDLPackDataType ,
235237{
236238 type Error = DLPackNDarrayError ;
237239
238- fn try_from ( array : ndarray:: ArrayView < ' a , T , D > ) -> Result < Self , Self :: Error > {
240+ fn try_from ( array : & ' a ndarray:: ArrayView < ' a , T , D > ) -> Result < Self , Self :: Error > {
239241 let tensor = array_to_tensor_view ( array) ?;
240242
241243 return Ok ( unsafe {
@@ -245,14 +247,14 @@ impl<'a, T, D> TryFrom<ndarray::ArrayView<'a, T, D>> for DLPackTensorRef<'a> whe
245247 }
246248}
247249
248- impl < ' a , T , D > TryFrom < ndarray:: ArrayViewMut < ' a , T , D > > for DLPackTensorRefMut < ' a > where
250+ impl < ' a , T , D > TryFrom < & ' a ndarray:: ArrayViewMut < ' a , T , D > > for DLPackTensorRefMut < ' a > where
249251 D : ndarray:: Dimension ,
250252 T : GetDLPackDataType ,
251253{
252254 type Error = DLPackNDarrayError ;
253255
254- fn try_from ( array : ndarray:: ArrayViewMut < ' a , T , D > ) -> Result < Self , Self :: Error > {
255- let tensor = array_to_tensor_view ( array. view ( ) ) ?;
256+ fn try_from ( array : & ' a ndarray:: ArrayViewMut < ' a , T , D > ) -> Result < Self , Self :: Error > {
257+ let tensor = array_to_tensor_view ( array) ?;
256258
257259 return Ok ( unsafe {
258260 // SAFETY: we are constraining the lifetime of the return value, and
@@ -269,7 +271,13 @@ impl<'a, T, D> TryFrom<&'a ndarray::Array<T, D>> for DLPackTensorRef<'a> where
269271 type Error = DLPackNDarrayError ;
270272
271273 fn try_from ( array : & ' a ndarray:: Array < T , D > ) -> Result < Self , Self :: Error > {
272- Self :: try_from ( array. view ( ) )
274+ let tensor = array_to_tensor_view ( array) ?;
275+
276+ return Ok ( unsafe {
277+ // SAFETY: we are constraining the lifetime of the return value, and
278+ // returning a mut ref from a mut ref
279+ DLPackTensorRef :: from_raw ( tensor)
280+ } ) ;
273281 }
274282}
275283
@@ -280,7 +288,13 @@ impl<'a, T, D> TryFrom<&'a mut ndarray::Array<T, D>> for DLPackTensorRefMut<'a>
280288 type Error = DLPackNDarrayError ;
281289
282290 fn try_from ( array : & ' a mut ndarray:: Array < T , D > ) -> Result < Self , Self :: Error > {
283- Self :: try_from ( array. view_mut ( ) )
291+ let tensor = array_to_tensor_view ( array) ?;
292+
293+ return Ok ( unsafe {
294+ // SAFETY: we are constraining the lifetime of the return value, and
295+ // returning a mut ref from a mut ref
296+ DLPackTensorRefMut :: from_raw ( tensor)
297+ } ) ;
284298 }
285299}
286300
@@ -467,7 +481,8 @@ mod tests {
467481 #[ test]
468482 fn test_ndarray_to_dlpack ( ) {
469483 let array = arr2 ( & [ [ 1i64 , 2 , 3 ] , [ 4 , 5 , 6 ] ] ) ;
470- let dlpack_ref = DLPackTensorRef :: try_from ( array. view ( ) ) . unwrap ( ) ;
484+ let view = array. view ( ) ;
485+ let dlpack_ref = DLPackTensorRef :: try_from ( & view) . unwrap ( ) ;
471486 let raw = dlpack_ref. raw ;
472487
473488 assert_eq ! ( raw. ndim, 2 ) ;
0 commit comments