Skip to content

Commit b3201ce

Browse files
authored
Add critical section guards to accessors (NVIDIA#2215)
* Add critical section guards to thread-sensitive accessors Protect accessors with cython critical sections so free-threaded execution avoids races when reading cached state. At least one of these was noticed by free-threaded test runs. I am not certain that they will guarantee identity returns, but pretty sure this will make them thread-safe. (The reason being that at least on non free-threaded builds they may release the GIL or, on free-threaded, do API calls that release the critical section temporarily.) About the `.pyi` fixes: I think these are incorrect but `cython` is already used in other places and shouldn't be a runtime/typing requirement at all. * Apply suggestion from @seberg
1 parent feb5ed4 commit b3201ce

7 files changed

Lines changed: 18 additions & 0 deletions

File tree

cuda_core/cuda/core/_memory/_buffer.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import cython
56
from cuda.core._memory._device_memory_resource import DeviceMemoryResource
67
from cuda.core._memory._ipc import IPCBufferDescriptor
78
from cuda.core._memory._pinned_memory_resource import PinnedMemoryResource
@@ -101,6 +102,7 @@ class Buffer:
101102
"""
102103

103104
@property
105+
@cython.critical_section
104106
def ipc_descriptor(self) -> IPCBufferDescriptor:
105107
"""Descriptor for sharing this buffer with other processes."""
106108

cuda_core/cuda/core/_memory/_buffer.pyx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ cdef class Buffer:
206206
return _ipc.Buffer_from_ipc_descriptor(cls, mr, ipc_descriptor, stream)
207207

208208
@property
209+
@cython.critical_section
209210
def ipc_descriptor(self) -> IPCBufferDescriptor:
210211
"""Descriptor for sharing this buffer with other processes."""
211212
if self._ipc_data is None:

cuda_core/cuda/core/_memory/_memory_pool.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ from __future__ import annotations
44

55
import uuid
66

7+
import cython
78
from cuda.core._memory._buffer import Buffer, MemoryResource
89
from cuda.core._stream import Stream
910
from cuda.core.graph import GraphBuilder
@@ -97,6 +98,7 @@ class _MemPool(MemoryResource):
9798
"""
9899

99100
@property
101+
@cython.critical_section
100102
def attributes(self) -> _MemPoolAttributes:
101103
"""Memory pool attributes."""
102104

cuda_core/cuda/core/_memory/_memory_pool.pyx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from __future__ import annotations
66

7+
cimport cython
78
from libc.limits cimport ULLONG_MAX
89
from libc.stdint cimport uintptr_t
910
from libc.string cimport memset
@@ -177,6 +178,7 @@ cdef class _MemPool(MemoryResource):
177178
_MP_deallocate(self, <uintptr_t>ptr, size, s)
178179

179180
@property
181+
@cython.critical_section
180182
def attributes(self) -> _MemPoolAttributes:
181183
"""Memory pool attributes."""
182184
if self._attributes is None:

cuda_core/cuda/core/_memoryview.pyx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from __future__ import annotations
66

7+
cimport cython
78
from ._dlpack cimport *
89
from ._dlpack import classify_dl_device
910
from libc.stdint cimport intptr_t
@@ -539,6 +540,7 @@ cdef class StridedMemoryView:
539540
+ f" readonly={self.readonly},\n"
540541
+ f" exporting_obj={get_simple_repr(self.exporting_obj)})")
541542
543+
@cython.critical_section
542544
cdef inline _StridedLayout get_layout(self):
543545
if self._layout is None:
544546
if self.dl_tensor:
@@ -549,6 +551,7 @@ cdef class StridedMemoryView:
549551
raise ValueError("Cannot infer layout from the exporting object")
550552
return self._layout
551553
554+
@cython.critical_section
552555
cdef inline object get_buffer(self):
553556
"""
554557
Returns Buffer instance with the underlying data.
@@ -562,6 +565,7 @@ cdef class StridedMemoryView:
562565
self._buffer = Buffer.from_handle(self.ptr, 0, owner=self.exporting_obj)
563566
return self._buffer
564567
568+
@cython.critical_section
565569
cdef inline object get_dtype(self):
566570
if self._dtype is None:
567571
if self.dl_tensor != NULL:

cuda_core/cuda/core/_module.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ from __future__ import annotations
55
from collections import namedtuple
66
from os import PathLike
77

8+
import cython
89
from cuda.core._device import Device
910
from cuda.core._launch_config import LaunchConfig
1011
from cuda.core._stream import Stream
@@ -253,6 +254,7 @@ class Kernel:
253254
...
254255

255256
@property
257+
@cython.critical_section
256258
def attributes(self) -> KernelAttributes:
257259
"""Get the read-only attributes of this kernel."""
258260

@@ -265,6 +267,7 @@ class Kernel:
265267
"""list[ParamInfo]: (offset, size) for each argument of this function"""
266268

267269
@property
270+
@cython.critical_section
268271
def occupancy(self) -> KernelOccupancy:
269272
"""Get the occupancy information for launching this kernel."""
270273

cuda_core/cuda/core/_module.pyx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from __future__ import annotations
66

7+
cimport cython
78
from libc.stddef cimport size_t
89

910
from collections import namedtuple
@@ -454,6 +455,7 @@ cdef class Kernel:
454455
return ker
455456

456457
@property
458+
@cython.critical_section
457459
def attributes(self) -> KernelAttributes:
458460
"""Get the read-only attributes of this kernel."""
459461
if self._attributes is None:
@@ -501,6 +503,7 @@ cdef class Kernel:
501503
return param_info
502504

503505
@property
506+
@cython.critical_section
504507
def occupancy(self) -> KernelOccupancy:
505508
"""Get the occupancy information for launching this kernel."""
506509
if self._occupancy is None:
@@ -742,6 +745,7 @@ cdef class ObjectCode:
742745

743746
# TODO: do we want to unload in a finalizer? Probably not..
744747

748+
@cython.critical_section
745749
cdef int _lazy_load_module(self) except -1:
746750
if self._h_library:
747751
return 0

0 commit comments

Comments
 (0)