Repository navigation
Carry loader_scratch_vm_allocate.patch: Apple loader scratch from vm_allocate - #46
Merged
Merged
Conversation
This was referenced Nov 15, 2026
Track retirement of loader_scratch_vm_allocate.patch (iOS loader scratch stays in the footprint)
#45
Closed
Draft
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #45. For llamadart #2004, plan #2011.
Root cause
#44 moved ggml host buffers to
vm_allocate, but on iOS 18 about 240 MiB stayed in libmalloc's cache after dispose. It is held byModelLoader::load_tensors's per-thread scratch vectors (read_buffer,convert_buffer,zip_entry_buffer,model_loader.cpp:1171-1173) andconvert_tensor'sbuf(:151). An interposer on v0.3.0-5 saw 28 to 56 MiB blocks from those threads (every one returned intoload_tensors(...)::$_0).Change
patches/loader_scratch_vm_allocate.patch: on Apple,TensorScratchovervm_allocate/vm_deallocate(grows tomax(size, 2*cap), keeps no contents, throwsstd::bad_alloc); other platforms keepstd::vector<uint8_t>. Replaces the three loader vectors andconvert_tensor's buffer. Thezip_entry_bufferhunk stays.CMakeLists.txtcarry line,patches/README.mdrow (patch-specific maintainer exception, retirement tracked in Track retirement of loader_scratch_vm_allocate.patch (iOS loader scratch stays in the footprint) #45; nothing posted upstream),README.mdcount of carried fixes (five to six).tests/test_loader_scratch_runtime.pyandtests/native/loader_scratch_runtime_test.cpp; macOS smoke step invalidate.yml(buildjob, after "Split graph evaluation",SD_REQUIRE_RUNTIME=1; GitHub's runners have no Metal, so the Metal case skips there).Footprint (SD-Turbo q8_0, M4 Max, macOS 26.7.1,
phys_footprintMiB, 3 load/decode/dispose cycles, 6 threads)Failing first
macos-arm64built from unpatched main with the new tests,SD_REQUIRE_RUNTIME=1 SD_REQUIRE_METAL_GENERATION=1: 4 failures (largest loader-threadoperator new: 147456 B CPU/F32, 2056192 B Metal/F32, same for BF16 convolutions). With the patch: OK, 184 B in all four cases.Mutations (largest loader-thread
operator new, bytes; threshold 16384)read_bufferto vectorconvert_bufferto vectorzip_entry_bufferto vectorconvert_tensorbufto vectorM3 survives because only a PyTorch ZIP checkpoint reaches
zip_entry_buffer; the hunk is kept for parity with the other scratch buffers and is untested.Validation (this Mac, M-series, Metal)
test_loader_scratch_runtime.py2 OK;test_fp8_runtime.py9 OK;test_graph_split_runtime.py2 OK;test_runtime_api.py1 OK.SD_REQUIRE_METAL_GENERATION=1 python3 -m unittest discover -s tests: 121 tests OK, 8 skipped (e.g. Linux and Dart-gated ones).validate_artifacts.pyok formacos-arm64andios-arm64. The patchedios-arm64dylib imports_vm_allocateand_vm_deallocate, and not_posix_memalignor___cxa_atexit.