(&self, name: &str)
| 469 | |
| 470 | impl TensorStorageProvider for SafetensorsStorage { |
| 471 | fn read_tensor(&self, name: &str) -> Result<TensorData> { |
| 472 | let meta = self |
| 473 | .index |
| 474 | .get(name) |
| 475 | .ok_or_else(|| anyhow::anyhow!("tensor '{}' not found in storage", name))?; |
| 476 | |
| 477 | let shard = self |
| 478 | .shards |
| 479 | .get(meta.shard_idx as usize) |
| 480 | .ok_or_else(|| anyhow::anyhow!("shard index {} out of range", meta.shard_idx))?; |
| 481 | |
| 482 | let size = meta.byte_size as usize; |
| 483 | |
| 484 | // mmap: zero-syscall read — just memcpy from mapped memory |
| 485 | #[cfg(unix)] |
| 486 | let buf = shard.read_bytes(meta.abs_offset, size); |
| 487 | |
| 488 | #[cfg(not(unix))] |
| 489 | let buf = { |
| 490 | use std::io::{Read, Seek, SeekFrom}; |
| 491 | let mut f = shard.file.try_clone()?; |
| 492 | let mut buf = vec![0u8; size]; |
| 493 | f.seek(SeekFrom::Start(meta.abs_offset))?; |
| 494 | f.read_exact(&mut buf)?; |
| 495 | buf |
| 496 | }; |
| 497 | |
| 498 | Ok(TensorData { |
| 499 | bytes: buf, |
| 500 | dtype: meta.dtype, |
| 501 | shape: meta.shape.to_vec(), |
| 502 | }) |
| 503 | } |
| 504 | |
| 505 | fn read_tensors(&self, names: &[&str]) -> Result<Vec<TensorData>> { |
| 506 | if names.is_empty() { |
no test coverage detected