Conversation
Each physical allocation, address reservation and mapping now lives in a std::shared_ptr handle whose deleter knows the exact driver call to undo it. A buffer owns a range of mappings through its device pointer handle, so everything a buffer maps is released when the last buffer that maps it closes, and a failed multi-step operation unwinds by letting its local handles die. The module moves from Python to Cython. The design is in cuda_core/cuda/core/_cpp/rt/VMM_DESIGN.md. Behavior changes: - modify_allocation returns a new VirtualMemoryBuffer and leaves the input open; the two alias the same physical memory, which is freed when the last of them closes. The pointer is preserved when the driver grants the adjacent address range. - Buffer.size after a grow is the aligned total. - config= applies to the chunk the call adds and is not stored on the resource. - Buffers from allocate() free themselves on close and do not call deallocate(), which now serves pointers wrapped with Buffer.from_handle. - A buffer records the stream passed to allocate(); the last close of an aliased range synchronizes every recorded stream before it unmaps. An explicit close on a capturing stream raises. - location_type="host" requires handle_type=None. allocate(0) returns an empty buffer without a driver call. Fixes NVIDIA#2887 Fixes NVIDIA#2907 Fixes NVIDIA#2908 Fixes NVIDIA#2909 Fixes NVIDIA#2886 Fixes NVIDIA#2345 Addresses NVIDIA#2388 item 2 and the size-0, misaligned-probe and host handle-type parts of NVIDIA#2910. Part of NVIDIA#2906. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This was referenced Sep 18, 2026
Contributor
|
The child interpreter inherited pytest's working directory, cuda_core/, so `import cuda.core` resolved to the uncompiled source tree in CI and failed on `cuda.core._version`. Use the shared run_python_snippet helper, which starts the child in an empty temporary directory. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Run the range deleter's stream sync in relaxed capture mode, so a capture on an unrelated stream is not invalidated. - Record a real stream on allocate(0) and inherit it on the grow. - Require handle_type=None for location "host" only. - Apply the constructor's option checks to a per-call modify_allocation config, including the RDMA support check. - Narrow the close() capture contract to non-default streams in the docstring, design doc and release note. - Tests: failed grow leaves the input intact, close during an unrelated capture, GC release during capture, deterministic stream sync with a sleep kernel, cuMemGetAccess on both chunks, graph retention across a grow, forced-move leak on 2 MiB that fails rather than skips. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The struct setter in cuda-bindings 13.0 accepts only the enum, and the Cython helper returns a plain int. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
sylvesterkaczmarek
left a comment
Contributor
There was a problem hiding this comment.
The no-access case can call this with count == 0 and descs.data() from an empty vector. Constructing access(descs, descs + count) then does pointer arithmetic/range construction on a possibly null pointer. Since self_access=None with no peers is supported, could this special-case zero descriptors before forming the range?
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
Moves
VirtualMemoryResourceonto the_rthandle layer, as planned in #2906 (design). Each physical allocation, address reservation and mapping is astd::shared_ptrhandle with a deleter that knows the exact driver call to undo it. A buffer owns a range of mappings through its device pointer handle, so everything a buffer maps is released when the last buffer that maps it closes, and a failed multi-step operation unwinds by letting its local handles die. The module moves from Python to Cython. The design lands ascuda_core/cuda/core/_cpp/rt/VMM_DESIGN.md.Behavior changes
modify_allocationreturns a newVirtualMemoryBufferand leaves the buffer passed in open. The two alias the same physical memory, which is freed when the last of them closes. The pointer is preserved when the driver grants the adjacent address range. A request the buffer already covers returns the buffer itself.Buffer.sizeafter a grow is the aligned total.config=applies to the chunk the call adds and is no longer stored on the resource. It must keep the resource's location and passes the constructor's option checks, including the RDMA support check.allocate()free themselves when they close and no longer calldeallocate(), which now serves pointers wrapped withBuffer.from_handle.allocate(). The last close of an aliased range synchronizes every recorded stream before it unmaps. An explicitclose()on a capturing stream other than a default stream raises; a release ordered on a default stream that would disturb a capture in its context is reported as aCUDAWarningand unmaps without the synchronization. The synchronization runs in relaxed capture mode, so it does not invalidate a capture on an unrelated stream.modify_allocationaccepts only buffers this resource returned.location_type="host"requireshandle_type=None, which the driver requires.allocate(0)returns an empty buffer without a driver call.Testing
cuMemGetAccesson both chunks after aconfig=grow, the per-call config checks, the raw-pointerdeallocate()path, host location without a current context, size zero with an inherited stream, and buffers alive at interpreter shutdown.close()until the launch completes and the graph is gone. A second test keeps the range mapped across a grow and the close of every alias.cuda_coresuite passed on an H100 with CUDA 13.4: 4288 passed, 106 skipped, 2 xfailed, 0 failed, and the VMM selection passed twice in random order. After the review round, the VMM selection (37 passed, 1 skipped) and the graph retention tests (3 passed) passed on an H200 with CUDA 13.4; CI covers the full suite.Issues
Fixes #2887
Fixes #2907
Fixes #2908
Fixes #2909
Fixes #2886
Fixes #2345
Fixes #2877
Addresses #2388 items 1, 2 and 3 (the rollback that lost access grants, the dead fast path, and the finalizer warnings; item 4 landed in #2418) and the size-0, misaligned-probe and host handle-type parts of #2910. Part of #2906. Supersedes #2880, #2889 and #2237: they edit the module this PR replaces, and the fixes they carried (#2877, #2886, #2345) are part of the redesign.
🤖 Generated with Claude Code