Skip to content

Commit 6de0c36

Browse files
committed
Cover VMM grow leaks and preserve map errors
1 parent d91108d commit 6de0c36

2 files changed

Lines changed: 16 additions & 7 deletions

File tree

cuda_core/cuda/core/_memory/_virtual_memory_resource.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ def allocate(self, size: int, *, stream: Stream | GraphBuilder | None = None) ->
538538
# ---- Create physical memory ----
539539
res, handle = driver.cuMemCreate(aligned_size, prop, 0)
540540
raise_if_driver_error(res)
541-
# Once mapped, the physical allocation is kept alive without the creation reference.
541+
# Drop the creation reference on either outcome; a successful mapping keeps the allocation alive.
542542
trans.on_exit(lambda h=handle: raise_if_driver_error(driver.cuMemRelease(h)[0]))
543543

544544
# ---- Reserve VA space ----
@@ -550,8 +550,8 @@ def allocate(self, size: int, *, stream: Stream | GraphBuilder | None = None) ->
550550

551551
# ---- Map physical memory into VA ----
552552
(res,) = driver.cuMemMap(ptr, aligned_size, 0, handle, 0)
553-
trans.on_failure(lambda p=ptr, s=aligned_size: raise_if_driver_error(driver.cuMemUnmap(p, s)[0]))
554553
raise_if_driver_error(res)
554+
trans.on_failure(lambda p=ptr, s=aligned_size: raise_if_driver_error(driver.cuMemUnmap(p, s)[0]))
555555

556556
# ---- Set access for owner + peers ----
557557
descs = self._build_access_descriptors(prop)

cuda_core/tests/test_memory.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,8 @@ def __init__(self, size):
10361036
assert ("release", NEW_HANDLE) in calls
10371037

10381038

1039-
def test_vmm_allocate_close_does_not_leak(init_cuda):
1039+
@pytest.mark.parametrize("grow", [False, True], ids=["allocate", "grow"])
1040+
def test_vmm_allocate_close_does_not_leak(init_cuda, grow):
10401041
device = Device()
10411042
if not device.properties.virtual_memory_management_supported:
10421043
pytest.skip("Virtual memory management is not supported on this device")
@@ -1045,13 +1046,21 @@ def test_vmm_allocate_close_does_not_leak(init_cuda):
10451046
device,
10461047
config=VirtualMemoryResourceOptions(handle_type="win32_kmt" if IS_WINDOWS else "posix_fd"),
10471048
)
1048-
buf = mr.allocate(8 * 1024 * 1024) # Warm up and learn the aligned allocation size.
1049-
aligned_size = buf.size
1050-
buf.close()
1049+
requested_size = 8 * 1024 * 1024
1050+
1051+
def allocate_and_close():
1052+
buf = mr.allocate(requested_size)
1053+
if grow:
1054+
buf = mr.modify_allocation(buf, 2 * buf.size)
1055+
aligned_size = buf.size
1056+
buf.close()
1057+
return aligned_size
1058+
1059+
aligned_size = allocate_and_close() # Warm up and learn the aligned allocation size.
10511060

10521061
baseline = handle_return(driver.cuMemGetInfo())[0]
10531062
for _ in range(8):
1054-
mr.allocate(8 * 1024 * 1024).close()
1063+
allocate_and_close()
10551064
free = handle_return(driver.cuMemGetInfo())[0]
10561065

10571066
# Current main leaks aligned_size per iteration; the fixed path stays near baseline.

0 commit comments

Comments
 (0)