| 60 | /// This avoids the flatten_all + to_vec1 + reinterpret chain in candle's data() path. |
| 61 | #[inline] |
| 62 | fn cpu_storage_bytes_range(storage: &candle_core::CpuStorage, start: usize, end: usize) -> Vec<u8> { |
| 63 | if start == end { |
| 64 | return Vec::new(); |
| 65 | } |
| 66 | use candle_core::CpuStorage; |
| 67 | macro_rules! extract { |
| 68 | ($slice:expr) => {{ |
| 69 | let data = &$slice[start..end]; |
| 70 | let byte_len = data.len() * std::mem::size_of_val(&data[0]); |
| 71 | let ptr = data.as_ptr() as *const u8; |
| 72 | unsafe { std::slice::from_raw_parts(ptr, byte_len) }.to_vec() |
| 73 | }}; |
| 74 | } |
| 75 | match storage { |
| 76 | CpuStorage::U8(s) => extract!(s), |
| 77 | CpuStorage::U32(s) => extract!(s), |
| 78 | CpuStorage::I16(s) => extract!(s), |
| 79 | CpuStorage::I32(s) => extract!(s), |
| 80 | CpuStorage::I64(s) => extract!(s), |
| 81 | CpuStorage::BF16(s) => extract!(s), |
| 82 | CpuStorage::F16(s) => extract!(s), |
| 83 | CpuStorage::F32(s) => extract!(s), |
| 84 | CpuStorage::F64(s) => extract!(s), |
| 85 | CpuStorage::F8E4M3(s) => extract!(s), |
| 86 | // Dummy dtype variants store raw bytes |
| 87 | CpuStorage::F6E2M3(s) | CpuStorage::F6E3M2(s) | CpuStorage::F4(s) | CpuStorage::F8E8M0(s) => { |
| 88 | s[start..end].to_vec() |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | impl RawTensor { |
| 94 | /// Convert x into a RawTensor. |