Skip to content

Commit f57003a

Browse files
authored
Merge branch 'main' into consolidate-driver-version
2 parents 2fe17c8 + a61cb05 commit f57003a

30 files changed

Lines changed: 6043 additions & 220 deletions

cuda_core/cuda/core/_layout.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

cuda_core/cuda/core/_linker.pyx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,23 @@ cdef class Linker:
168168
else:
169169
return as_py(self._culink_handle)
170170

171-
@property
172-
def backend(self) -> CompilerBackendType:
173-
"""Return this Linker instance's underlying :class:`CompilerBackendType`."""
174-
return CompilerBackendType.NVJITLINK if self._use_nvjitlink else CompilerBackendType.DRIVER
171+
@classmethod
172+
def which_backend(cls) -> CompilerBackendType:
173+
"""Return which linking backend will be used.
174+
175+
Returns :attr:`~CompilerBackendType.NVJITLINK` when the nvJitLink
176+
library is available and meets the minimum version requirement,
177+
otherwise :attr:`~CompilerBackendType.DRIVER`.
178+
179+
.. note::
180+
181+
Prefer letting :class:`Linker` decide. Query ``which_backend()``
182+
only when you need to dispatch based on input format (for
183+
example: choose PTX vs. LTOIR before constructing a
184+
``Linker``). The returned value names an implementation
185+
detail whose support matrix may shift across CTK releases.
186+
"""
187+
return CompilerBackendType.DRIVER if _decide_nvjitlink_or_driver() else CompilerBackendType.NVJITLINK
175188

176189

177190
# =============================================================================

cuda_core/cuda/core/_memory/_device_memory_resource.pxd

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ from cuda.core._memory._ipc cimport IPCDataForMR
99
cdef class DeviceMemoryResource(_MemPool):
1010
cdef:
1111
int _dev_id
12-
object _peer_accessible_by
1312

1413

1514
cpdef DMR_mempool_get_access(DeviceMemoryResource, int)

cuda_core/cuda/core/_memory/_device_memory_resource.pyx

Lines changed: 10 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ from cuda.core._utils.cuda_utils cimport (
1818
check_or_create_options,
1919
HANDLE_RETURN,
2020
)
21-
from cpython.mem cimport PyMem_Malloc, PyMem_Free
22-
2321
from dataclasses import dataclass
2422
import multiprocessing
2523
import platform # no-cython-lint
2624
import uuid
2725

28-
from cuda.core._memory._peer_access_utils import plan_peer_access_update
26+
from cuda.core._memory._peer_access_utils import PeerAccessibleBySetProxy, replace_peer_accessible_by
2927
from cuda.core._utils.cuda_utils import check_multiprocessing_start_method
3028

3129
__all__ = ['DeviceMemoryResource', 'DeviceMemoryResourceOptions']
@@ -131,7 +129,6 @@ cdef class DeviceMemoryResource(_MemPool):
131129

132130
def __cinit__(self, *args, **kwargs):
133131
self._dev_id = cydriver.CU_DEVICE_INVALID
134-
self._peer_accessible_by = None
135132

136133
def __init__(self, device_id: Device | int, options=None):
137134
_DMR_init(self, device_id, options)
@@ -191,7 +188,6 @@ cdef class DeviceMemoryResource(_MemPool):
191188
_ipc.MP_from_allocation_handle(cls, alloc_handle))
192189
from .._device import Device
193190
mr._dev_id = Device(device_id).device_id
194-
mr._peer_accessible_by = ()
195191
return mr
196192

197193
@property
@@ -217,30 +213,23 @@ cdef class DeviceMemoryResource(_MemPool):
217213
pool. Access can be modified at any time and affects all allocations
218214
from this memory pool.
219215
220-
Returns a tuple of sorted device IDs that currently have peer access to
221-
allocations from this memory pool.
222-
223-
When setting, accepts a sequence of :obj:`~_device.Device` objects or device IDs.
224-
Setting to an empty sequence revokes all peer access.
225-
226-
For non-owned pools (the default or current device pool), the state
227-
is always queried from the driver to reflect changes made by other
228-
wrappers or direct driver calls.
216+
Returns a set-like proxy of :obj:`~_device.Device` objects that manages
217+
peer access. Inputs are accepted as either :obj:`~_device.Device`
218+
objects or device-ordinal :class:`int` values.
229219
230220
Examples
231221
--------
232222
>>> dmr = DeviceMemoryResource(0)
233-
>>> dmr.peer_accessible_by = [1] # Grant access to device 1
234-
>>> assert dmr.peer_accessible_by == (1,)
235-
>>> dmr.peer_accessible_by = [] # Revoke access
223+
>>> dmr.peer_accessible_by = {1} # grant access to device 1
224+
>>> assert 1 in dmr.peer_accessible_by
225+
>>> dmr.peer_accessible_by.add(2) # update access to include device 2
226+
>>> dmr.peer_accessible_by = [] # revoke peer access
236227
"""
237-
if not self._mempool_owned:
238-
_DMR_query_peer_access(self)
239-
return self._peer_accessible_by
228+
return PeerAccessibleBySetProxy(self)
240229

241230
@peer_accessible_by.setter
242231
def peer_accessible_by(self, devices):
243-
_DMR_set_peer_accessible_by(self, devices)
232+
replace_peer_accessible_by(self, devices)
244233

245234
@property
246235
def is_device_accessible(self) -> bool:
@@ -253,81 +242,6 @@ cdef class DeviceMemoryResource(_MemPool):
253242
return False
254243

255244

256-
cdef inline _DMR_query_peer_access(DeviceMemoryResource self):
257-
"""Query the driver for the actual peer access state of this pool."""
258-
cdef int total
259-
cdef cydriver.CUmemAccess_flags flags
260-
cdef cydriver.CUmemLocation location
261-
cdef list peers = []
262-
263-
with nogil:
264-
HANDLE_RETURN(cydriver.cuDeviceGetCount(&total))
265-
266-
location.type = cydriver.CUmemLocationType.CU_MEM_LOCATION_TYPE_DEVICE
267-
for dev_id in range(total):
268-
if dev_id == self._dev_id:
269-
continue
270-
location.id = dev_id
271-
with nogil:
272-
HANDLE_RETURN(cydriver.cuMemPoolGetAccess(&flags, as_cu(self._h_pool), &location))
273-
if flags == cydriver.CUmemAccess_flags.CU_MEM_ACCESS_FLAGS_PROT_READWRITE:
274-
peers.append(dev_id)
275-
276-
self._peer_accessible_by = tuple(sorted(peers))
277-
278-
279-
cdef inline _DMR_set_peer_accessible_by(DeviceMemoryResource self, devices):
280-
from .._device import Device
281-
282-
this_dev = Device(self._dev_id)
283-
cdef object resolve_device_id = lambda dev: Device(dev).device_id
284-
cdef object plan
285-
cdef tuple target_ids
286-
cdef tuple to_add
287-
cdef tuple to_rm
288-
if not self._mempool_owned:
289-
_DMR_query_peer_access(self)
290-
plan = plan_peer_access_update(
291-
owner_device_id=self._dev_id,
292-
current_peer_ids=self._peer_accessible_by,
293-
requested_devices=devices,
294-
resolve_device_id=resolve_device_id,
295-
can_access_peer=this_dev.can_access_peer,
296-
)
297-
target_ids = plan.target_ids
298-
to_add = plan.to_add
299-
to_rm = plan.to_remove
300-
cdef size_t count = len(to_add) + len(to_rm)
301-
cdef cydriver.CUmemAccessDesc* access_desc = NULL
302-
cdef size_t i = 0
303-
304-
if count > 0:
305-
access_desc = <cydriver.CUmemAccessDesc*>PyMem_Malloc(count * sizeof(cydriver.CUmemAccessDesc))
306-
if access_desc == NULL:
307-
raise MemoryError("Failed to allocate memory for access descriptors")
308-
309-
try:
310-
for dev_id in to_add:
311-
access_desc[i].flags = cydriver.CUmemAccess_flags.CU_MEM_ACCESS_FLAGS_PROT_READWRITE
312-
access_desc[i].location.type = cydriver.CUmemLocationType.CU_MEM_LOCATION_TYPE_DEVICE
313-
access_desc[i].location.id = dev_id
314-
i += 1
315-
316-
for dev_id in to_rm:
317-
access_desc[i].flags = cydriver.CUmemAccess_flags.CU_MEM_ACCESS_FLAGS_PROT_NONE
318-
access_desc[i].location.type = cydriver.CUmemLocationType.CU_MEM_LOCATION_TYPE_DEVICE
319-
access_desc[i].location.id = dev_id
320-
i += 1
321-
322-
with nogil:
323-
HANDLE_RETURN(cydriver.cuMemPoolSetAccess(as_cu(self._h_pool), access_desc, count))
324-
finally:
325-
if access_desc != NULL:
326-
PyMem_Free(access_desc)
327-
328-
self._peer_accessible_by = tuple(target_ids)
329-
330-
331245
cdef inline _DMR_init(DeviceMemoryResource self, device_id, options):
332246
from .._device import Device
333247
cdef int dev_id = Device(device_id).device_id
@@ -351,7 +265,6 @@ cdef inline _DMR_init(DeviceMemoryResource self, device_id, options):
351265
self._mempool_owned = False
352266
MP_raise_release_threshold(self)
353267
else:
354-
self._peer_accessible_by = ()
355268
MP_init_create_pool(
356269
self,
357270
cydriver.CUmemLocationType.CU_MEM_LOCATION_TYPE_DEVICE,

cuda_core/cuda/core/_memory/_ipc.pyx

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

cuda_core/cuda/core/_memory/_peer_access_utils.py

Lines changed: 0 additions & 59 deletions
This file was deleted.

0 commit comments

Comments
 (0)