Repository navigation
fix(cuda.core): grant the current device access to PinnedMemoryResource pools #3405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,8 @@ from cuda.core._memory._memory_pool cimport ( | |
| ) | ||
| from cuda.core._memory cimport _ipc | ||
| from cuda.core._memory._ipc cimport IPCAllocationHandle | ||
| from cuda.core._memory._location cimport cumemlocation_from_id | ||
| from cuda.core._rt cimport as_cu | ||
| from cuda.core._stream cimport Stream, Stream_accept | ||
| from cuda.core._utils.cuda_utils cimport ( | ||
| check_or_create_options, | ||
|
|
@@ -99,6 +101,12 @@ cdef class PinnedMemoryResource(_MemPool): | |
| is unsupported and stream-ordered allocation is not needed, use | ||
| :class:`LegacyPinnedMemoryResource`. | ||
|
|
||
| The driver makes a host memory pool accessible only from the host by | ||
| default, so the resource grants the device that is current when it is | ||
| created read and write access to the pool. Kernels on other devices cannot | ||
| access its buffers. Without options, the grant applies to the driver's | ||
| current pool, which the whole process shares. | ||
|
|
||
| To create an IPC-Enabled memory resource (MR) that is capable of sharing | ||
| allocations between processes, specify ``ipc_enabled=True`` in the initializer | ||
| option. When IPC is enabled and ``numa_id`` is not specified, the NUMA node | ||
|
|
@@ -141,13 +149,7 @@ cdef class PinnedMemoryResource(_MemPool): | |
| raise TypeError("Cannot allocate from a mapped IPC-enabled memory resource") | ||
| cdef Stream s = Stream_accept(stream) | ||
| device = s.device | ||
| cdef bint supported = ( | ||
| device.properties.host_numa_memory_pools_supported | ||
| if self._numa_id >= 0 | ||
| else device.properties.host_memory_pools_supported | ||
| ) | ||
|
|
||
| if not supported: | ||
| if not _host_pool_supported(device, self._numa_id): | ||
| raise RuntimeError( | ||
| f"CUDA device {device.device_id} does not support the requested " | ||
| "host memory pool for PinnedMemoryResource. Use " | ||
|
|
@@ -244,7 +246,7 @@ cdef class PinnedMemoryResource(_MemPool): | |
|
|
||
| @property | ||
| def is_device_accessible(self) -> bool: | ||
| """Return True. This memory resource provides device-accessible buffers.""" | ||
| """Return True. The device that is current when the resource is created can read and write its buffers.""" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| return True | ||
|
|
||
| @property | ||
|
|
@@ -253,6 +255,14 @@ cdef class PinnedMemoryResource(_MemPool): | |
| return True | ||
|
|
||
|
|
||
| cdef inline bint _host_pool_supported(device, int numa_id): | ||
| return ( | ||
| device.properties.host_numa_memory_pools_supported | ||
| if numa_id >= 0 | ||
| else device.properties.host_memory_pools_supported | ||
| ) | ||
|
|
||
|
|
||
| cdef inline _PMR_init(PinnedMemoryResource self, options): | ||
| from .._device import Device | ||
|
|
||
|
|
@@ -264,6 +274,7 @@ cdef inline _PMR_init(PinnedMemoryResource self, options): | |
| cdef size_t max_size = 0 | ||
| cdef cydriver.CUmemLocationType loc_type | ||
| cdef int numa_id = -1 | ||
| cdef cydriver.CUmemAccessDesc access | ||
|
|
||
| if opts is not None: | ||
| ipc_enabled = opts.ipc_enabled | ||
|
|
@@ -309,6 +320,17 @@ cdef inline _PMR_init(PinnedMemoryResource self, options): | |
| max_size, | ||
| ) | ||
|
|
||
| # A pool on a host location is accessible only from the host by default | ||
| # (see cuMemPoolCreate), so grant the current device read/write access. A | ||
| # device without host pool support cannot allocate from it anyway. | ||
| dev = Device() | ||
| if _host_pool_supported(dev, numa_id): | ||
| access.location = cumemlocation_from_id( | ||
| cydriver.CUmemLocationType.CU_MEM_LOCATION_TYPE_DEVICE, dev.device_id) | ||
| access.flags = cydriver.CUmemAccess_flags.CU_MEM_ACCESS_FLAGS_PROT_READWRITE | ||
| with nogil: | ||
| HANDLE_RETURN(cydriver.cuMemPoolSetAccess(as_cu(self._h_pool), &access, 1)) | ||
|
|
||
|
|
||
| def _deep_reduce_pinned_memory_resource(mr: object) -> tuple[object, ...]: | ||
| check_multiprocessing_start_method() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script executed:
Repository: NVIDIA/cuda-python
Length of output: 20733
Web query:
CUDA driver API cuMemGetMemPool host location current pool CU_MEM_LOCATION_TYPE_HOST cuMemPoolSetAccess other device access flags independentResult:
Script executed:
Repository: NVIDIA/cuda-python
Length of output: 1675
Web query:
CUDA 13 driver cuMemPoolSetAccess "specified" locations "access" map allocations does not affect other locationsResult:
Script executed:
Repository: NVIDIA/cuda-python
Length of output: 7737
Web query:
site:docs.nvidia.com/cuda/archive/13.0.0/cuda-driver-api/group__CUDA__MALLOC__ASYNC.html "cuMemPoolSetAccess" "The access" "locations"Result:
important: Qualify the other-device access claim.
Two resources created without options can share the current pool. If they are created on different supported devices, both devices can retain access to all allocations in that pool. Qualify the claim here and in
_pinned_memory_resource.pyi.