np.memmap vs np.load mmap_mode for writable large arrays under memory pressure
0 reputation · 21 Sept 2020, 08:57 UTC
0 reputation · 21 Sept 2020, 08:57 UTC
Working with arrays that exceed available RAM requires memory-mapped file access. NumPy provides two documented entry points: np.memmap for explicit control over offset, shape, and mode, and np.load with mmap_mode for a simpler loading API. Both avoid eager allocation for read-only workloads, but the constraint shifts when the array must be modified in place.
The target environment has limited physical memory and a read-write dataset larger than RAM. The application needs deterministic persistence semantics: changes should reach durable storage without manual flush() calls scattered through the codebase, yet the process cannot afford a full in-memory copy.
NumPy does not standardize copy-on-write or automatic flushing guarantees for writable mappings. np.memmap exposes flush() but leaves flush timing and dirty-page propagation to the OS. np.load with mmap_mode='r+' or 'c' (copy-on-write) offers fewer parameters and its write-back behavior varies by platform and NumPy version. Neither approach documents a portable contract for when modifications become visible to other processes or survive a crash.
Which approach gives more predictable write persistence for a memory-constrained writer: the explicit np.memmap with manual flush discipline, or np.load with mmap_mode='c' relying on OS copy-on-write? Does either provide a documented guarantee that surviving pages reflect the last written state after an unclean shutdown?
31775 reputation · 21 Sept 2020, 11:52 UTC
Use np.memmap with mode 'r+' (or 'w+') and call flush() at explicit checkpoints. This gives deterministic control over when dirty pages reach the file system. np.load(..., mmap_mode='c') relies on copy‑on‑write and the interpreter’s garbage collector to write back changes, which is nondeterministic and can consume extra memory under pressure.
Neither API documents a guarantee that data survives an unclean shutdown; durability depends on OS page‑cache behavior and whether a flush or deallocation occurs before the crash.
np.memmap is more predictableflush() forces the OS to write dirty pages; you decide when.np.load(mmap_mode='c')flush() is called on that array.Both approaches leave data in the OS page cache until a flush or sync occurs. An abrupt process termination (SIGKILL, power loss) can lose any unflushed pages. For stronger durability you must call os.fsync(fd) on the underlying file descriptor after flush().
arr = np.memmap('test.dat', dtype='float64', mode='w+', shape=(1000,))arr.flush(), then os.fsync(arr.fileno()).np.load('test.dat', mmap_mode='c'), modify, let the array go out of scope (or call flush()), then crash; observe whether the write appears.Does the application already call flush() (or os.fsync) before normal termination? If not, adding explicit flush points to np.memmap is the only way to get predictable persistence.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.