Skip to content

Commit 9d977be

Browse files
rparolinclaude
andcommitted
cuda.core: make managed-prefetch test page-size aware
TestPrefetchBatch.test_per_buffer_location hardcoded a 4096-byte allocation and assumed two pooled buffers landed on separate physical pages. Managed-memory prefetch and CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION operate at page granularity, so on nvidia-64k aarch64 kernels both 4 KB buffers shared one 64 KB page; prefetching buf[1] to the device migrated the shared page and buf[0]'s host prefetch reported device 0 (assert 0 == -1). Derive the allocation size from mmap.PAGESIZE so each buffer occupies a full page on every platform, and add a precondition asserting the two buffers sit on distinct pages so a pool-packing regression fails loudly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d717605 commit 9d977be

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

cuda_core/tests/memory/test_managed_ops.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4+
import mmap
5+
46
import pytest
57
from helpers.buffers import DummyDeviceMemoryResource, DummyUnifiedMemoryResource
68

@@ -9,7 +11,14 @@
911
from cuda.core import Device, Host, ManagedBuffer
1012
from cuda.core._memory._managed_buffer import _get_int_attr
1113

12-
_MANAGED_TEST_ALLOCATION_SIZE = 4096
14+
# Managed-memory prefetch and CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION
15+
# operate at physical-page granularity. Test buffers must each occupy a full
16+
# page; otherwise the pool packs sub-page allocations into one page and
17+
# per-buffer prefetch locations become indistinguishable. ``mmap.PAGESIZE``
18+
# tracks the OS page size (4 KiB on most x86, 64 KiB on nvidia-64k aarch64
19+
# kernels), so allocations stay one-page-per-buffer on every platform.
20+
_PAGE_SIZE = mmap.PAGESIZE
21+
_MANAGED_TEST_ALLOCATION_SIZE = _PAGE_SIZE
1322
_READ_MOSTLY_ENABLED = 1
1423
_HOST_LOCATION_ID = -1
1524
_INVALID_HOST_DEVICE_ORDINAL = 0
@@ -21,6 +30,12 @@ def _last_prefetch_location(buf):
2130
return _get_int_attr(buf, driver.CUmem_range_attribute.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION)
2231

2332

33+
def _page_base(buf):
34+
# Page-aligned base of the buffer's start address; two buffers sharing a
35+
# page cannot be prefetched to different locations independently.
36+
return int(buf.handle) & ~(_PAGE_SIZE - 1)
37+
38+
2439
def _skip_if_raw_managed_alloc_unsupported(device):
2540
# Raw `cuMemAllocManaged` capability — distinct from conftest's
2641
# `skip_if_managed_memory_unsupported`, which gates `ManagedMemoryResource`
@@ -216,6 +231,10 @@ def test_per_buffer_location(self, location_ops_device, location_ops_mr):
216231

217232
device = location_ops_device
218233
bufs = [location_ops_mr.allocate(_MANAGED_TEST_ALLOCATION_SIZE, stream=device.default_stream) for _ in range(2)]
234+
# Per-buffer prefetch locations are only observable when the buffers sit
235+
# on distinct physical pages; assert that here so a pool-packing change
236+
# fails loudly instead of silently migrating one shared page.
237+
assert _page_base(bufs[0]) != _page_base(bufs[1])
219238
stream = device.create_stream()
220239

221240
prefetch_batch(stream, bufs, [Host(), device])

0 commit comments

Comments
 (0)