Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cuda_bindings/pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ cuda-python-test-helpers = { path = "../cuda_python_test_helpers", editable = tr
[feature.docs.dependencies]
cuda-bindings = "13.2.*"
python = "3.12.*"
cython = ">=3.2.5,<3.3"
cython = ">=3.3,<3.4"
enum_tools = "*"
make = "*"
myst-nb = "*"
Expand All @@ -44,7 +44,7 @@ sphinx-copybutton = "*"
sphinx-toolbox = "*"

[feature.cython-tests.dependencies]
cython = ">=3.2.5,<3.3" # for tests that exercise APIs from cython
cython = ">=3.3,<3.4" # for tests that exercise APIs from cython
setuptools = "*" # for distutils
gxx = "*" # to compile the generated code
# These are necessary because running the Cython tests requires compiling
Expand Down Expand Up @@ -118,7 +118,7 @@ python = "*"
cuda-version = "*"
setuptools = ">=80"
setuptools-scm = ">=8"
cython = ">=3.2.5,<3.3"
cython = ">=3.3,<3.4"
cuda-pathfinder = { path = "../cuda_pathfinder" }
cuda-cudart-static = "*"
cuda-nvrtc-dev = "*"
Expand Down
4 changes: 2 additions & 2 deletions cuda_bindings/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
requires = [
"setuptools>=80.0.0",
"setuptools_scm[simple]>=8,!=10.1",
"cython>=3.2.5,<3.3",
"cython>=3.3,<3.4",
"cuda-pathfinder>=1.5",
]
build-backend = "build_hooks"
Expand Down Expand Up @@ -43,7 +43,7 @@ all = [

[dependency-groups]
test = [
"cython>=3.2.5,<3.3",
"cython>=3.3,<3.4",
"setuptools>=80.0.0",
# TODO: remove the Python 3.15 guard once 3.15 is officially supported
"matplotlib>=3.5.0,<=3.10.9; python_version < '3.15'",
Expand Down
4 changes: 2 additions & 2 deletions cuda_bindings/tests/test_cuda.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,12 +579,12 @@ def test_eglFrame():
assert int(val.frame.pArray[0]) == 0
assert int(val.frame.pArray[1]) == 0
assert int(val.frame.pArray[2]) == 0
val.frame.pArray = [1, 2, 3]
val.frame.pArray = [cuda.CUarray(x) for x in (1, 2, 3)]
# [<CUarray 0x1>, <CUarray 0x2>, <CUarray 0x3>]
assert int(val.frame.pArray[0]) == 1
assert int(val.frame.pArray[1]) == 2
assert int(val.frame.pArray[2]) == 3
val.frame.pArray = [cuda.CUarray(4), 2, 3]
val.frame.pArray = [cuda.CUarray(x) for x in (4, 2, 3)]
# [<CUarray 0x4>, <CUarray 0x2>, <CUarray 0x3>]
assert int(val.frame.pArray[0]) == 4
assert int(val.frame.pArray[1]) == 2
Expand Down
4 changes: 2 additions & 2 deletions cuda_bindings/tests/test_cudart.py
Original file line number Diff line number Diff line change
Expand Up @@ -1285,12 +1285,12 @@ def test_cudart_eglFrame():
assert int(frame.frame.pArray[0]) == 0
assert int(frame.frame.pArray[1]) == 0
assert int(frame.frame.pArray[2]) == 0
frame.frame.pArray = [1, 2, 3]
frame.frame.pArray = [cudart.cudaArray_t(x) for x in (1, 2, 3)]
# [<cudaArray_t 0x1>, <cudaArray_t 0x2>, <cudaArray_t 0x3>]
assert int(frame.frame.pArray[0]) == 1
assert int(frame.frame.pArray[1]) == 2
assert int(frame.frame.pArray[2]) == 3
frame.frame.pArray = [1, 2, cudart.cudaArray_t(4)]
frame.frame.pArray = [cudart.cudaArray_t(x) for x in (1, 2, 4)]
# [<cudaArray_t 0x1>, <cudaArray_t 0x2>, <cudaArray_t 0x4>]
assert int(frame.frame.pArray[0]) == 1
assert int(frame.frame.pArray[1]) == 2
Expand Down
4 changes: 2 additions & 2 deletions cuda_core/cuda/core/_device_resources.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class SMResourceOptions:
preferred_coscheduled_sm_count: int | SequenceABC[int] | None = None
backfill: bool | SequenceABC[bool] = False

@dataclass
@dataclass(init=False)
class WorkqueueResourceOptions:
"""Customizable :obj:`WorkqueueResource.configure` options.

Expand All @@ -60,7 +60,7 @@ class WorkqueueResourceOptions:
sharing_scope: WorkqueueSharingScopeType | str | None = None
concurrency_limit: int | None = None

def __post_init__(self): ...
def __init__(self, sharing_scope: WorkqueueSharingScopeType | str | None=None, concurrency_limit: int | None=None): ...

class SMResource:
"""Represent an SM (streaming multiprocessor) resource partition.
Expand Down
21 changes: 16 additions & 5 deletions cuda_core/cuda/core/_device_resources.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,12 @@ cdef class SMResourceOptions:
backfill: bool | SequenceABC[bool] = False


@dataclass
# init=False: Cython 3.3 wraps the dataclass-generated __init__ in a
# critical_section and then warns (promoted to an error by our
# warning_errors=True build) that the __post_init__ call inside it is
# unprotected Python attribute access. A hand-written __init__ sidesteps
# that; construction of a not-yet-shared object needs no lock anyway.
@dataclass(init=False)
cdef class WorkqueueResourceOptions:
"""Customizable :obj:`WorkqueueResource.configure` options.

Expand All @@ -147,13 +152,19 @@ cdef class WorkqueueResourceOptions:
sharing_scope: WorkqueueSharingScopeType | str | None = None
concurrency_limit: int | None = None

def __post_init__(self):
def __init__(
self,
sharing_scope: WorkqueueSharingScopeType | str | None = None,
concurrency_limit: int | None = None,
):
from cuda.core.typing import WorkqueueSharingScopeType
check_str_enum(self.sharing_scope, WorkqueueSharingScopeType, allow_none=True)
if self.concurrency_limit is not None and self.concurrency_limit < 1:
check_str_enum(sharing_scope, WorkqueueSharingScopeType, allow_none=True)
if concurrency_limit is not None and concurrency_limit < 1:
raise ValueError(
f"concurrency_limit must be >= 1, got {self.concurrency_limit}"
f"concurrency_limit must be >= 1, got {concurrency_limit}"
)
self.sharing_scope = sharing_scope
self.concurrency_limit = concurrency_limit


cdef inline int _validate_split_field_length(
Expand Down
18 changes: 13 additions & 5 deletions cuda_core/cuda/core/_memory/_buffer.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -404,16 +404,24 @@ cdef class Buffer:
return _ipc.Buffer_from_ipc_descriptor(cls, mr, ipc_descriptor, stream)

@property
@cython.critical_section
def ipc_descriptor(self) -> IPCBufferDescriptor:
"""Descriptor for sharing this buffer with other processes."""
Buffer_check_open(self)
cdef object ipc_data
if self._ipc_data is None:
# The critical section only protects the cdef-level check-and-set of
# self._ipc_data; the Python-level IPCDataForBuffer construction and
# .ipc_descriptor read happen outside the lock (Cython 3.3 warns that
# Python attribute access is not usefully protected by critical_section).
with cython.critical_section(self):
ipc_data = self._ipc_data
if ipc_data is None:
ipc_data = IPCDataForBuffer(_ipc.Buffer_get_ipc_descriptor(self), False)
if self._ipc_data is None:
self._ipc_data = ipc_data
return self._ipc_data.ipc_descriptor
with cython.critical_section(self):
if self._ipc_data is None:
self._ipc_data = ipc_data
else:
ipc_data = self._ipc_data
return ipc_data.ipc_descriptor

def close(self, stream: Stream | GraphBuilder | None = None) -> None:
"""Deallocate this buffer asynchronously on the given stream.
Expand Down
37 changes: 26 additions & 11 deletions cuda_core/cuda/core/_memoryview.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -560,28 +560,36 @@ cdef class StridedMemoryView:
self._layout = layout
return self._layout

@cython.critical_section
cdef inline object get_buffer(self):
"""
Returns Buffer instance with the underlying data.
If the SMV was created from a Buffer, it will return the same Buffer instance.
Otherwise, it will create a new instance with owner set to the exporting object.
"""
cdef object buffer
if self._buffer is None:
with cython.critical_section(self):
buffer = self._buffer
if buffer is None:
if isinstance(self.exporting_obj, Buffer):
buffer = self.exporting_obj
else:
buffer = Buffer.from_handle(self.ptr, 0, owner=self.exporting_obj)
if self._buffer is None:
self._buffer = buffer
return self._buffer
# The critical section only protects the cdef-level check-and-set
# of self._buffer; the Python-level Buffer construction above
# happens outside the lock (Cython 3.3 warns that Python attribute
# access is not usefully protected by critical_section).
with cython.critical_section(self):
if self._buffer is None:
self._buffer = buffer
else:
buffer = self._buffer
return buffer

@cython.critical_section
cdef inline object get_dtype(self):
cdef object dtype
if self._dtype is None:
dtype = None
with cython.critical_section(self):
dtype = self._dtype
if dtype is None:
if self.dl_tensor != NULL:
dtype = dtype_dlpack_to_numpy(&self.dl_tensor.dtype)
elif isinstance(self.metadata, int):
Expand All @@ -590,9 +598,16 @@ cdef class StridedMemoryView:
self.metadata)
elif self.metadata is not None:
dtype = _typestr2dtype(self.metadata["typestr"])
if self._dtype is None:
self._dtype = dtype
return self._dtype
# The critical section only protects the cdef-level check-and-set
# of self._dtype; the Python-level dtype resolution above happens
# outside the lock (Cython 3.3 warns that Python attribute access
# is not usefully protected by critical_section).
with cython.critical_section(self):
if self._dtype is None:
self._dtype = dtype
else:
dtype = self._dtype
return dtype


cdef void _smv_pycapsule_deleter(object capsule) noexcept:
Expand Down
6 changes: 3 additions & 3 deletions cuda_core/pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ CUDA_HOME = "$CONDA_PREFIX/targets/sbsa-linux"
CUDA_HOME = "$CONDA_PREFIX/Library"

[feature.cython-tests.dependencies]
cython = ">=3.2.5,<3.3" # for tests that exercise APIs from cython
cython = ">=3.3,<3.4" # for tests that exercise APIs from cython
setuptools = "*" # for distutils
gxx = "*" # to compile the generated code
# These are necessary because running the Cython tests requires compiling
Expand Down Expand Up @@ -97,7 +97,7 @@ cuda-version = "12.*"

[feature.docs.dependencies]
cuda-core = { path = "." }
cython = ">=3.2.5,<3.3"
cython = ">=3.3,<3.4"
myst-parser = "*"
numpy = "*"
numpydoc = "*"
Expand Down Expand Up @@ -214,7 +214,7 @@ python = "*"
cuda-version = "*"
setuptools = ">=80"
setuptools-scm = ">=8"
cython = ">=3.2.5,<3.3"
cython = ">=3.3,<3.4"
cuda-nvrtc-dev = "*"
cuda-bindings = "*"
dlpack = "*"
Expand Down
4 changes: 2 additions & 2 deletions cuda_core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
requires = [
"setuptools>=80",
"setuptools-scm[simple]>=8,!=10.1",
"Cython>=3.2.5,<3.3",
"Cython>=3.3,<3.4",
"cuda-pathfinder>=1.5"
]
build-backend = "build_hooks"
Expand Down Expand Up @@ -59,7 +59,7 @@ cu13 = ["cuda-bindings[all]==13.*", "cuda-toolkit==13.*"]

[dependency-groups]
test = [
"cython>=3.2.5,<3.3",
"cython>=3.3,<3.4",
"setuptools>=80",
"pytest==9.1.0",
"pytest-benchmark==5.2.3",
Expand Down
2 changes: 1 addition & 1 deletion cuda_pathfinder/pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pytest-run-parallel = ">=0.4.1"
# Keep this dependency set aligned with cuda_python/docs/environment-docs.yml.
[feature.docs.dependencies]
python = "3.12.*"
cython = ">=3.2.5,<3.3"
cython = ">=3.3,<3.4"
enum_tools = "*"
make = "*"
myst-nb = "*"
Expand Down
2 changes: 1 addition & 1 deletion cuda_python/docs/environment-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ channels:
dependencies:
# ATTENTION: This dependency list is duplicated in
# toolshed/setup-docs-env.sh. Please KEEP THEM IN SYNC!
- cython >=3.2.5,<3.3
- cython >=3.3,<3.4
- myst-parser
- numpy
- numpydoc
Expand Down
2 changes: 1 addition & 1 deletion toolshed/setup-docs-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ echo "Creating environment '${ENV_NAME}'…"
# cuda_python/docs/environment-docs.yml. Please KEEP THEM IN SYNC!
conda create -y -n "${ENV_NAME}" \
"python=${PYVER}" \
"cython>=3.2.5,<3.3" \
"cython>=3.3,<3.4" \
myst-parser \
numpy \
numpydoc \
Expand Down
Loading