feat(agent): track POSIX CUDA VMM state - #205
Closed
galletas1712 wants to merge 1 commit into
Closed
galletas1712 wants to merge 1 commit into
galletas1712 wants to merge 1 commit into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueComment |
Turn the forwarding shim into one that knows which CUDA allocations are shared between processes. Allocations created with exactly the POSIX file-descriptor handle type are tracked behind logical handles; every other handle type passes through untouched. Exports return sealed memfd tickets instead of the driver's descriptor; an import of a ticket asks the creator process for the real descriptor over its control socket. The creator answers from an export cache that holds the one real descriptor per allocation, so its listener never calls into the driver and never takes the shim's main lock, and a creator busy inside a long collective call cannot stall its peers. Bookkeeping lives in hash tables plus a sorted range index that shrink as well as grow; records are freed when no handle and no mapping remains, so a server that maps and unmaps for days does not accumulate dead entries or slow down. One driver handle backs each allocation per process: repeated imports and cuMemRetainAllocationHandle alias it, and the last logical handle releases it. A ticket lives as long as the creator holds a handle or mapping, so freeing memory frees it. cuMemSetAccess keeps the union of access per location so one call per peer GPU survives; a call that partly overlaps a tracked mapping, or would grant more than 32 locations, is refused before the driver sees it. cuMemMap refuses overlapping a tracked mapping and cuMemUnmap may cover several whole mappings but not cut through one. Imports of descriptors that are not tickets are counted so the coordinator can refuse to checkpoint while one is alive. Fork children drop inherited records and register on their first CUDA activity, including through the driver's own symbol resolution, so a child that initializes CUDA without VMM calls is still visible. The multicast wrappers translate tracked member handles for the bind calls and otherwise still forward. The shim does not yet answer the coordinator's lifecycle requests; that is the next change. Compared with the earlier tracking layers (#152, #166): the export happens once at ticket time instead of on demand under the main lock; access sets are merged per location instead of overwritten by the last call; lists that never shrank are replaced by tables that do; the CUDA context is captured at creation rather than only at export; unmap and map are range-checked; the listener retries transient accept errors; the socket path is chmod 0600; NULL and non-zero-flag exports return CUDA_ERROR_INVALID_VALUE as the driver does. Fourteen state tests, table and export-cache unit tests, and the earlier suites run under AddressSanitizer and UndefinedBehaviorSanitizer during the agent image build. Signed-off-by: Schwinn Saereesitthipitak <schwinns@nvidia.com>
galletas1712
force-pushed
the
feat/cuinterpose-posix-tracking
branch
from
September 4, 2026 17:52
8a19292 to
b05e96b
Compare
Contributor
Author
|
Superseded by the nine-PR re-cut (packaging → delivery → agent → forwarding → coordinator → tracking → lifecycle → multicast → GPU tests): Go and packaging split by component, tests trimmed, docs held back. The replacement PRs are listed on the packaging PR. |
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.
Summary
Allocation tracking without the lifecycle. Doc:
docs/reference/cuinterpose.md§3.1 and §6 (creator anchor, one driver reference per allocation, access merging, lock order).table.c: open-addressing hash tables (logical handle, allocation id) and a sorted range index for mappings, both shrinking as well as growing.interpose.c: exact POSIX descriptor handle type tracked, everything else passes through (one log line for FABRIC); logical handles (0xd94dtag); one driver handle per allocation per process (imports andcuMemRetainAllocationHandlealias it);cuMemMaprefuses overlaps,cuMemUnmapis range-based,cuMemSetAccessmerges per location, refuses partial overlaps, and marks a mapping unknown after a driver failure so prepare fails closed; raw imports counted; records freed with the last handle and mapping.export_cache.c: the one real export per allocation, served to peers by the listener with only the cache lock (no driver call, no state lock); per-entry drain on drop; quiesce/resume for the lifecycle.accept4retry with backoff,chmod 0600on the socket path, 10 s socket timeouts, fork handlers.state_preload_test(alias collapse, range unmap, access merging andPROT_NONE, tickets, imports from a forked child through the listener, raw import counting, churn leaving the tables empty, descriptor exhaustion),table_unit_test, export cache tests inproto_unit_test.Origin
Re-cut of the tracking parts of #152 and #166.
#152 feat(agent): checkpoint POSIX CUDA VMM state (verbatim, bot blocks removed)
#166 fix(agent): collapse duplicate CUDA handle references (verbatim, bot blocks removed)
Review threads carried
No review threads on #152 or #166. The #78 threads on
interpose.care fixed here; see PR 2's table.Validation
go test ./...inapi,operator,agent;make lint,make helm-lint,make verify-license-headers.cuda-checkpoint --launch-job): POSIX round trip with seeded 1 GiB carriers per rank, multicast round trip with PyTorch's multimem all-reduce and acuMulticastBindAddrrebind, refusal while a raw import is alive: 3 passed. Host-carrier restore phase 87 to 108 GB/s aggregate over two GPUs (pinned-copy baseline 55 GB/s per GPU).AsyncLLM, Qwen3-0.6B, tensor parallel 2, FlashInfer TRT-LLM attention and fused allreduce (trtllmbackend), PodSnapshot of a Deployment shaped withpodcontract.ShapeCuinterposeCapture, then restore: checkpoint 52 s (CRIU dump 49 s, cuinterpose prepare 0.43 s; 4 CUDA processes, 1052 records, 382 host carriers, 2.08 GB); restore 5.7 s (cuinterpose 0.35 s: carriers 0.05 s, unicast 0.09 s, multicast 0.18 s); the restored replica answers coherently ("The capital of Italy is Rome").🤖 Generated with Claude Code