Repository navigation
--shared-expert-arena: one engine loads the file, the others wait and attach - #2271
i-Vladimir-i wants to merge 3 commits into
Conversation
… attach The shared arena (Niko1221#129) mapped one file for every engine, but each engine still read the whole pack into it, with nothing to keep two loads apart. Now two OFD locks on the file coordinate them: the first engine loads it and publishes it ready, an engine started meanwhile waits and then attaches without reading, and a later start attaches while the file is there. An engine that dies while loading leaves the file to the next one; a file of another pack, size or format is replaced when no engine maps it and refused while one does. The header is one 2 MiB page (format V2), so the arena is 2 MiB-aligned and hugetlbfs can hold the file. The file is allocated up front (ENOSPC instead of SIGBUS on a small tmpfs), mapped before the GPU registration, and the loading engine makes its 2 MiB pages whole with MADV_COLLAPSE; the start reports how much is on 2 MiB pages. On AMD that matters: hipHostRegister does not pin, and compaction moving 4 KB pages stops the GPU queues (measurements in bench/results/2026-10-13-community-r9700-shared-expert-arena). Without the flag nothing changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pages under the Niko1221#2126 rule (free 2 MiB blocks for half of it, STRATA_ARENA_THP=1 asks anyway; not on hugetlbfs) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1340e01 to
d5e1cee
Compare
|
Rebased on v0.1.44 (
Checked again on the rebased branch (R9700, gfx1201, ROCm 7.14.1):
🤖 Generated with Claude Code |
|
Hi! We also touch Your The textual overlap ( Proposal: keep both platform branches in one |
|
Found by reading (no Mac here to build): |
… engine compiles pinned.cu) sys/vfs.h, fstatfs, posix_fallocate, the OFD locks and the smaps reader were in the non-Windows branch, which the Metal build also compiles. They are now under __linux__; elsewhere a shared file is refused as on Windows. Review: qiuzan2001 in Niko1221#2271. Also: the error path's ftruncate result is checked (gcc's warn_unused_result warned on the cast).
|
Thanks, right: the Metal build compiles Checked: HIP (gfx1201) builds and |
|
Agreed, the overlap is only textual: your chunked large pages are under |
|
Thanks. This saves RAM and start time when two engines serve one pack; it does not change tokens per second, so it is outside this speed round and we have not ported it. It would need a rebase and a two-engine test on one box. |
|
Thanks for the pull request. We're resetting the tracker for 0.2.0-beta. There are more than 1,300 open issues and pull requests, too many for us to review properly, so we're closing everything that isn't being worked on right now. Closed here does not mean rejected. To reopen it takes about two minutes:
The rules are in CONTRIBUTING.md. |
--shared-expert-arena: one engine loads the file, the others wait and attach#129 added the shared arena as a primitive and left two things to the caller: who loads the file ("no
leader/follower population protocol yet") and its lifetime. Today every engine that names the file reads the whole
pack into it again at start - 55 GiB for UD-IQ4_XS, written into pages another engine may be reading - and nothing
keeps two loads apart. This adds that part, inside the engine, so two engines of one pack (one per GPU, each with its
own expert cache and K/V; #1461's pair is one such setup) keep one RAM copy and load it once.
What it changes (
src/core/pinned.cu,pinned.hpp,expert_source.cpp/.hpp,generate.cpp; the selftest;DETAILS.md; measurements inbench/results/2026-10-13-community-r9700-shared-expert-arena/)when an engine exits or dies). FILL is held by the engine that loads the file until the load passed its checks; an
engine started meanwhile waits on it (
shared arena ...: engine N is loading it, waiting) and then attaches - noread of the pack,
attached 55.43 GiB another engine loaded, nothing read. USER is held shared while an engine mapsthe file.
engine that dies while loading leaves the file to the next one, which loads it again. A file of another pack, size or
format is replaced when no engine maps it (USER taken exclusively, then unlinked - never truncated under a mapping)
and refused while one does.
hugetlbfs can hold it (the V1 comment said it could not). V1 files are replaced like any other format when unused.
posix_fallocate: a tmpfs smaller than the arena is an error naming thesize, not a SIGBUS part-way through the load), mapped before the GPU registration (
MADV_POPULATE_*, Linux 5.14),and the loading engine makes its 2 MiB pages whole with
MADV_COLLAPSE(Linux 6.1) while they are still empty. Thestart reports
N of M GiB on 2 MiB pages; on AMD, when part of it is on 4 KB pages, it says why that matters.hipHostRegisterdoes not pin host memory on ROCm 7.14.1 (VmPin0); thekernel's compaction moves 4 KB pages, and every move stops the process's GPU queues while the driver maps the range
again. With 16 GiB registered, one forced compaction: 194-295 ms of stopped queues on 4 KB pages, 0-18 ms on a tmpfs
huge=always; CPU reads and host->device copies were the same on both (table inDETAILS.md, method and the otherbackings - hugetlbfs,
hipHostMalloc,hipMemCreateon the host - in the bench folder).What it leaves alone: without
--shared-expert-arenanothing changes -PinnedArenawithout a file takes the oldpath,
shared_publish()is a no-op, andArenaExpertSource's load is the same code one level deeper. The SYCL treekeeps its own V1 copy of the option: a V1 engine refuses a V2 file (size and header do not match) rather than
misreading it, and since it takes no locks its V1 file counts as unused here - unlinked, not truncated, so it keeps
its mapping. Linux only: the code is under
__linux__; on Windows (as before) and on other platforms, macOSincluded, a shared file is refused with "implemented on Linux only".
Checked
ple_parityas before (needs the Q2_0 model).pinned_shared_test, rewritten for the protocol, runs the other engines as child processes: the second waits whilethe first loads and attaches once it publishes; an attach in the same process; another pack and another size
refused while mapped; a restart attaches; a file of another pack held by another process refused, replaced once
that process is gone; a loader killed before publishing leaves the file to the next one. Run on
/dev/shmand on ahugetlbfs mount (
STRATA_TEST_ARENA_DIR): both report the file whole on 2 MiB pages. CUDA: builds and links withnvcc 13.4.92, sm_120, 0 errors; not run on an NVIDIA GPU.
--spec 4 --mtp, 48 greedy tokens, tmpfssize=58G,huge=always,noswap:STRATA_VERIFY_ARENA=1)The load itself is about 32 s here (1.7-1.8 GiB/s from the file cache); the rest of a start is the same either way.
With the smaller caches the tokens differ from the reference from the 6th on, both engines alike - which experts a
card holds changes the rounding, as the docs say for other cache sizes. The fresh file of the second run was on 2 MiB
pages for 50.6 of 55.4 GiB (the machine had just freed a 55 GiB arena;
MADV_COLLAPSEcould not make the restwhole), the fourth for all of it after
MADV_COLLAPSE.the experts in RAM (69 GB of 125 GB still available with both running), 512 greedy tokens each:
huge=alwaysvm.nr_overcommit_hugepages)Same checksum everywhere; each engine's tokens the same alone and in the pair. A forced compaction during the pair's
decode stopped the x16 engine's queues 0 ms in three of four runs and the x4 engine's 0.6-0.7 s in each, on tmpfs and
hugetlbfs alike - memory other than the arena, not traced here. The hugetlbfs pages (28,384) went back to the system
when the file was deleted. The engine runs on hugetlbfs were made before a fix of the start line's count (hugetlb
pages are in
Shared_Hugetlb, notRss: it said 0 of 55.44 GiB); the selftest on a hugetlbfs mount(
STRATA_TEST_ARENA_DIR) now shows the file whole on 2 MiB pages.Not tested: NVIDIA at run time (
cudaHostRegisterpins the file's pages there); the server (serve/) running twoengines (#1461's desk is one); kernels older than 6.1 (
MADV_COLLAPSEthen reports itself unavailable in the startline).
🤖 Generated with Claude Code