@@ -47,6 +47,36 @@ pub trait TensorStorageProvider: Send + Sync {
4747 fn tensor_names ( & self ) -> Vec < String > ;
4848}
4949
50+ /// Max tensor dimensions supported (covers all practical shapes).
51+ const MAX_DIMS : usize = 4 ;
52+
53+ /// Inline shape storage — avoids Vec heap allocation for shapes up to 4 dims.
54+ #[ derive( Debug , Clone , Copy ) ]
55+ struct InlineShape {
56+ dims : [ usize ; MAX_DIMS ] ,
57+ ndim : u8 ,
58+ }
59+
60+ impl InlineShape {
61+ fn from_vec ( v : & [ usize ] ) -> Self {
62+ let mut dims = [ 0usize ; MAX_DIMS ] ;
63+ let ndim = v. len ( ) . min ( MAX_DIMS ) ;
64+ dims[ ..ndim] . copy_from_slice ( & v[ ..ndim] ) ;
65+ Self {
66+ dims,
67+ ndim : ndim as u8 ,
68+ }
69+ }
70+
71+ fn as_slice ( & self ) -> & [ usize ] {
72+ & self . dims [ ..self . ndim as usize ]
73+ }
74+
75+ fn to_vec ( self ) -> Vec < usize > {
76+ self . as_slice ( ) . to_vec ( )
77+ }
78+ }
79+
5080/// Metadata for a single tensor within a safetensors shard file.
5181#[ derive( Debug , Clone ) ]
5282struct TensorMeta {
@@ -58,8 +88,8 @@ struct TensorMeta {
5888 byte_size : u64 ,
5989 /// Data type.
6090 dtype : DType ,
61- /// Shape.
62- shape : Vec < usize > ,
91+ /// Shape (inline, no heap allocation for shapes <= 4 dims) .
92+ shape : InlineShape ,
6393}
6494
6595/// Reads individual tensors from safetensors files using `pread()`.
@@ -238,7 +268,7 @@ impl SafetensorsStorage {
238268 }
239269 } ;
240270
241- let shape : Vec < usize > = meta
271+ let shape_vec : Vec < usize > = meta
242272 . get ( "shape" )
243273 . and_then ( |v| v. as_array ( ) )
244274 . map ( |arr| {
@@ -253,7 +283,7 @@ impl SafetensorsStorage {
253283 abs_offset,
254284 byte_size,
255285 dtype,
256- shape,
286+ shape : InlineShape :: from_vec ( & shape_vec ) ,
257287 } ) )
258288 }
259289}
@@ -290,7 +320,7 @@ impl TensorStorageProvider for SafetensorsStorage {
290320 Ok ( TensorData {
291321 bytes : buf,
292322 dtype : meta. dtype ,
293- shape : meta. shape . clone ( ) ,
323+ shape : meta. shape . to_vec ( ) ,
294324 } )
295325 }
296326
@@ -352,7 +382,7 @@ impl TensorStorageProvider for SafetensorsStorage {
352382 results. push ( TensorData {
353383 bytes,
354384 dtype : meta. dtype ,
355- shape : meta. shape . clone ( ) ,
385+ shape : meta. shape . to_vec ( ) ,
356386 } ) ;
357387 offset += size;
358388 }
@@ -403,7 +433,7 @@ mod tests {
403433 assert_eq ! ( tm. abs_offset, 8 + 200 ) ;
404434 assert_eq ! ( tm. byte_size, 1048576 ) ;
405435 assert_eq ! ( tm. dtype, DType :: F16 ) ;
406- assert_eq ! ( tm. shape, vec![ 1024 , 512 ] ) ;
436+ assert_eq ! ( tm. shape. to_vec ( ) , vec![ 1024 , 512 ] ) ;
407437 }
408438
409439 #[ test]
@@ -430,7 +460,7 @@ mod tests {
430460 abs_offset : 108 ,
431461 byte_size : 1024 ,
432462 dtype : DType :: F32 ,
433- shape : vec ! [ 16 , 16 ] ,
463+ shape : InlineShape :: from_vec ( & [ 16 , 16 ] ) ,
434464 } ,
435465 ) ;
436466 m
0 commit comments