pub struct MappedFile { /* private fields */ }Expand description
A file’s bytes in array storage: on a Mac with a GPU, the file is memory-mapped and wrapped as GPU-visible memory without a copy, so arrays made from it are views whose pages are read when first touched (by the CPU or the GPU). Elsewhere the file is read into memory. The mapping lives as long as any array made from it.
The file must not be modified (written or truncated, by this or another process) while
it is mapped: arrays made from it would change underneath their readers (undefined
behaviour), and reads past a truncated end raise SIGBUS. Map only files nothing
writes while they are in use, such as model weights.
use nuvec_core::{DType, MappedFile};
let path = std::env::temp_dir().join("nuvec-mapped-file-doc.bin");
let bytes: Vec<u8> = [1.0f32, 2.0, 3.0, 4.0].iter().flat_map(|v| v.to_le_bytes()).collect();
std::fs::write(&path, &bytes).unwrap();
let file = MappedFile::open(&path)?;
let a = file.array(4, DType::F32, &[3])?; // bytes 4..16, no copy
assert_eq!(a.to_vec::<f32>()?, vec![2.0, 3.0, 4.0]);Implementations§
Source§impl MappedFile
impl MappedFile
Sourcepub fn open(path: impl AsRef<Path>) -> Result<Self>
pub fn open(path: impl AsRef<Path>) -> Result<Self>
Maps (or reads) the file at path. The file must not be modified while it is
mapped (see MappedFile).
Sourcepub fn mapping_size(len: u64) -> u64
pub fn mapping_size(len: u64) -> u64
The bytes mapping a file of len bytes holds in the GPU allocator’s mapped
statistic: the whole file, rounded up to pages.
Sourcepub fn copy_size(len: u64) -> u64
pub fn copy_size(len: u64) -> u64
The bytes storage of len bytes (as MappedFile::read_ranges allocates) holds in
the GPU allocator’s active statistic: its size class.
Sourcepub fn headroom() -> Option<u64>
pub fn headroom() -> Option<u64>
The bytes that may still be mapped or allocated before the GPU’s memory limit
(memory_limit − active − mapped), or None without a GPU.
Sourcepub fn read_ranges(
path: impl AsRef<Path>,
ranges: &[(u64, usize, usize)],
len: usize,
) -> Result<Self>
pub fn read_ranges( path: impl AsRef<Path>, ranges: &[(u64, usize, usize)], len: usize, ) -> Result<Self>
Reads parts of the file at path into new array storage of len bytes, without
mapping it: each (file_offset, offset, n) of ranges puts the file’s bytes
file_offset..file_offset + n at offset..offset + n. For files whose arrays are
not aligned to their element sizes (safetensors written without header padding, as
MLX writes them): the ranges are placed so that every array is aligned, and arrays
made from the result are views of it. Bytes outside the ranges are unspecified.
The ranges must be in increasing order of offset and must not overlap. They are
read with positioned reads in chunks of 16 MiB, on up to 8 threads (one per 64 MiB
read), straight into the storage: from the page cache this runs at memory
bandwidth, and nothing but the storage is allocated (the file is not mapped).
use nuvec_core::{DType, MappedFile};
let path = std::env::temp_dir().join("nuvec-read-ranges-doc.bin");
// One padding byte, then three f32s: misaligned in the file.
let mut bytes = vec![0u8];
bytes.extend([1.0f32, 2.0, 3.0].iter().flat_map(|v| v.to_le_bytes()));
std::fs::write(&path, &bytes).unwrap();
let file = MappedFile::read_ranges(&path, &[(1, 0, 12)], 12)?;
assert_eq!(file.array(0, DType::F32, &[3])?.to_vec::<f32>()?, vec![1.0, 2.0, 3.0]);Trait Implementations§
Source§impl Clone for MappedFile
impl Clone for MappedFile
Auto Trait Implementations§
impl !RefUnwindSafe for MappedFile
impl !UnwindSafe for MappedFile
impl Freeze for MappedFile
impl Send for MappedFile
impl Sync for MappedFile
impl Unpin for MappedFile
impl UnsafeUnpin for MappedFile
Blanket Implementations§
impl<T> AutoreleaseSafe for Twhere
T: ?Sized,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more