From 1c6a5e1674078c7bad662411e23b8f684f5b38d1 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 02:08:25 +0000 Subject: [PATCH 01/18] cuda.core: expose driver-populated fields on WorkqueueResource Add read-only sharing_scope, concurrency_limit, and device properties on WorkqueueResource so users can inspect the driver-populated config without dropping to raw cydriver. Add WorkqueueSharingScopeType StrEnum in cuda.core.typing to give the sharing scope a typed return; strings matching the enum member values remain accepted for backward compat. Follows section 5(d) "opaque but round-trippable" from the green ctx design doc, which was written into SMResource but not applied to WorkqueueResource. --- cuda_core/cuda/core/_device_resources.pyi | 41 +++++++++-- cuda_core/cuda/core/_device_resources.pyx | 68 +++++++++++++++++-- cuda_core/cuda/core/typing.py | 16 +++++ cuda_core/docs/source/release/1.1.0-notes.rst | 9 +++ cuda_core/tests/test_green_context.py | 11 ++- 5 files changed, 136 insertions(+), 9 deletions(-) diff --git a/cuda_core/cuda/core/_device_resources.pyi b/cuda_core/cuda/core/_device_resources.pyi index 8ae6fb6b326..2a0d040da9e 100644 --- a/cuda_core/cuda/core/_device_resources.pyi +++ b/cuda_core/cuda/core/_device_resources.pyi @@ -5,6 +5,9 @@ from __future__ import annotations from collections.abc import Sequence as SequenceABC from dataclasses import dataclass +from cuda.core._device import Device +from cuda.core.typing import WorkqueueSharingScopeType + @dataclass class SMResourceOptions: @@ -44,9 +47,13 @@ class WorkqueueResourceOptions: Attributes ---------- - sharing_scope : str, optional - Workqueue sharing scope. Accepted values: ``"device_ctx"`` - or ``"green_ctx_balanced"``. (Default to ``None``) + sharing_scope : :class:`~cuda.core.typing.WorkqueueSharingScopeType`, optional + Workqueue sharing scope. Accepted values: + :attr:`~cuda.core.typing.WorkqueueSharingScopeType.DEVICE_CTX` or + :attr:`~cuda.core.typing.WorkqueueSharingScopeType.GREEN_CTX_BALANCED`. + Raw strings equal to the enum member values (``"device_ctx"``, + ``"green_ctx_balanced"``) are accepted at runtime for backward + compatibility. (Default to ``None``) concurrency_limit : int, optional Expected maximum number of concurrent stream-ordered workloads. Must be ``>= 1`` when set. The effective @@ -55,7 +62,7 @@ class WorkqueueResourceOptions: this cap, but the driver will not guarantee that work submission remains non-overlapping. (Default to ``None``) """ - sharing_scope: str | None = None + sharing_scope: WorkqueueSharingScopeType | None = None concurrency_limit: int | None = None def __post_init__(self): @@ -125,6 +132,32 @@ class WorkqueueResource: def handle(self) -> int: """Return the address of the underlying config ``CUdevResource`` struct.""" + @property + def sharing_scope(self) -> WorkqueueSharingScopeType: + """Current sharing scope of this workqueue resource. + + Returns the :class:`~cuda.core.typing.WorkqueueSharingScopeType` + member corresponding to the driver-populated + ``wqConfig.sharingScope`` field. It can be updated via + :meth:`configure` with + :attr:`WorkqueueResourceOptions.sharing_scope`. + """ + + @property + def concurrency_limit(self) -> int: + """Current expected maximum concurrent stream-ordered workloads. + + Reflects the driver-populated ``wqConfig.wqConcurrencyLimit`` field. + When first queried from a device, this matches the driver-reported + cap (typically ``CUDA_DEVICE_MAX_CONNECTIONS``). It can be updated + via :meth:`configure` with + :attr:`WorkqueueResourceOptions.concurrency_limit`. + """ + + @property + def device(self) -> 'Device': + """The :class:`~cuda.core.Device` this workqueue resource is available on.""" + def configure(self, options: WorkqueueResourceOptions) -> None: """Configure the workqueue resource in place. diff --git a/cuda_core/cuda/core/_device_resources.pyx b/cuda_core/cuda/core/_device_resources.pyx index 1e1f016f6cc..105da07af63 100644 --- a/cuda_core/cuda/core/_device_resources.pyx +++ b/cuda_core/cuda/core/_device_resources.pyx @@ -6,6 +6,11 @@ from __future__ import annotations from collections.abc import Sequence as SequenceABC from dataclasses import dataclass +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from cuda.core._device import Device + from cuda.core.typing import WorkqueueSharingScopeType from libc.stdint cimport intptr_t from libc.stdlib cimport free, malloc @@ -126,9 +131,13 @@ cdef class WorkqueueResourceOptions: Attributes ---------- - sharing_scope : str, optional - Workqueue sharing scope. Accepted values: ``"device_ctx"`` - or ``"green_ctx_balanced"``. (Default to ``None``) + sharing_scope : :class:`~cuda.core.typing.WorkqueueSharingScopeType`, optional + Workqueue sharing scope. Accepted values: + :attr:`~cuda.core.typing.WorkqueueSharingScopeType.DEVICE_CTX` or + :attr:`~cuda.core.typing.WorkqueueSharingScopeType.GREEN_CTX_BALANCED`. + Raw strings equal to the enum member values (``"device_ctx"``, + ``"green_ctx_balanced"``) are accepted at runtime for backward + compatibility. (Default to ``None``) concurrency_limit : int, optional Expected maximum number of concurrent stream-ordered workloads. Must be ``>= 1`` when set. The effective @@ -138,7 +147,7 @@ cdef class WorkqueueResourceOptions: submission remains non-overlapping. (Default to ``None``) """ - sharing_scope: str | None = None + sharing_scope: WorkqueueSharingScopeType | None = None concurrency_limit: int | None = None def __post_init__(self): @@ -554,6 +563,57 @@ cdef class WorkqueueResource: """Return the address of the underlying config ``CUdevResource`` struct.""" return (&self._wq_config_resource) + @property + def sharing_scope(self) -> WorkqueueSharingScopeType: + """Current sharing scope of this workqueue resource. + + Returns the :class:`~cuda.core.typing.WorkqueueSharingScopeType` + member corresponding to the driver-populated + ``wqConfig.sharingScope`` field. It can be updated via + :meth:`configure` with + :attr:`WorkqueueResourceOptions.sharing_scope`. + """ + IF CUDA_CORE_BUILD_MAJOR >= 13: + from cuda.core.typing import WorkqueueSharingScopeType + cdef object scope = self._wq_config_resource.wqConfig.sharingScope + if scope == cydriver.CUdevWorkqueueConfigScope.CU_WORKQUEUE_SCOPE_DEVICE_CTX: + return WorkqueueSharingScopeType.DEVICE_CTX + elif scope == cydriver.CUdevWorkqueueConfigScope.CU_WORKQUEUE_SCOPE_GREEN_CTX_BALANCED: + return WorkqueueSharingScopeType.GREEN_CTX_BALANCED + raise RuntimeError(f"Unknown sharing scope enum value: {scope}") + ELSE: + raise RuntimeError( + "WorkqueueResource requires cuda.core to be built with CUDA 13.x bindings" + ) + + @property + def concurrency_limit(self) -> int: + """Current expected maximum concurrent stream-ordered workloads. + + Reflects the driver-populated ``wqConfig.wqConcurrencyLimit`` field. + When first queried from a device, this matches the driver-reported + cap (typically ``CUDA_DEVICE_MAX_CONNECTIONS``). It can be updated + via :meth:`configure` with + :attr:`WorkqueueResourceOptions.concurrency_limit`. + """ + IF CUDA_CORE_BUILD_MAJOR >= 13: + return self._wq_config_resource.wqConfig.wqConcurrencyLimit + ELSE: + raise RuntimeError( + "WorkqueueResource requires cuda.core to be built with CUDA 13.x bindings" + ) + + @property + def device(self) -> "Device": + """The :class:`~cuda.core.Device` this workqueue resource is available on.""" + IF CUDA_CORE_BUILD_MAJOR >= 13: + from cuda.core._device import Device # avoid circular import + return Device(int(self._wq_config_resource.wqConfig.device)) + ELSE: + raise RuntimeError( + "WorkqueueResource requires cuda.core to be built with CUDA 13.x bindings" + ) + def configure(self, options: WorkqueueResourceOptions) -> None: """Configure the workqueue resource in place. diff --git a/cuda_core/cuda/core/typing.py b/cuda_core/cuda/core/typing.py index 2d253d8ca5e..1bf9bb7c0d2 100644 --- a/cuda_core/cuda/core/typing.py +++ b/cuda_core/cuda/core/typing.py @@ -52,6 +52,7 @@ class StrEnum(str, Enum): "VirtualMemoryGranularityType", "VirtualMemoryHandleType", "VirtualMemoryLocationType", + "WorkqueueSharingScopeType", ] @@ -296,4 +297,19 @@ class ReadModeType(StrEnum): NORMALIZED_FLOAT = "normalized_float" +class WorkqueueSharingScopeType(StrEnum): + """Sharing scope for :class:`~cuda.core.WorkqueueResource`. + + * ``DEVICE_CTX`` — use all shared workqueue resources across all + contexts (default driver behavior). + * ``GREEN_CTX_BALANCED`` — when possible, use non-overlapping + workqueue resources with other balanced green contexts. + + .. versionadded:: 1.1.0 + """ + + DEVICE_CTX = "device_ctx" + GREEN_CTX_BALANCED = "green_ctx_balanced" + + del StrEnum diff --git a/cuda_core/docs/source/release/1.1.0-notes.rst b/cuda_core/docs/source/release/1.1.0-notes.rst index d9fe0a7a5b4..f699446d9bb 100644 --- a/cuda_core/docs/source/release/1.1.0-notes.rst +++ b/cuda_core/docs/source/release/1.1.0-notes.rst @@ -110,6 +110,15 @@ New features configure the expected maximum concurrent stream-ordered workloads. (`#2329 `__) +- Added read-only :attr:`WorkqueueResource.sharing_scope`, + :attr:`~WorkqueueResource.concurrency_limit`, and + :attr:`~WorkqueueResource.device` properties for round-tripping the + driver-populated workqueue config. Added + :class:`~cuda.core.typing.WorkqueueSharingScopeType` StrEnum accepted + by :attr:`WorkqueueResourceOptions.sharing_scope` in addition to + raw strings. + (`#NNNN `__) + Fixes and enhancements ---------------------- diff --git a/cuda_core/tests/test_green_context.py b/cuda_core/tests/test_green_context.py index ee3896c53ec..64022b233e3 100644 --- a/cuda_core/tests/test_green_context.py +++ b/cuda_core/tests/test_green_context.py @@ -22,6 +22,7 @@ launch, ) from cuda.core._utils.cuda_utils import CUDAError +from cuda.core.typing import WorkqueueSharingScopeType # --------------------------------------------------------------------------- # Kernel source @@ -207,8 +208,11 @@ def test_arch_constraints_hopper_plus(self, init_cuda, sm_resource): class TestWorkqueueResource: - def test_query(self, wq_resource): + def test_query(self, init_cuda, wq_resource): assert wq_resource.handle != 0 + assert isinstance(wq_resource.sharing_scope, WorkqueueSharingScopeType) + assert wq_resource.concurrency_limit >= 1 + assert wq_resource.device.device_id == init_cuda.device_id def test_configure_none_is_noop(self, wq_resource): assert wq_resource.configure(WorkqueueResourceOptions(sharing_scope=None)) is None @@ -216,12 +220,17 @@ def test_configure_none_is_noop(self, wq_resource): def test_configure_valid_scope(self, wq_resource): wq_resource.configure(WorkqueueResourceOptions(sharing_scope="green_ctx_balanced")) + def test_configure_scope_with_enum(self, wq_resource): + wq_resource.configure(WorkqueueResourceOptions(sharing_scope=WorkqueueSharingScopeType.GREEN_CTX_BALANCED)) + assert wq_resource.sharing_scope is WorkqueueSharingScopeType.GREEN_CTX_BALANCED + def test_invalid_scope_raises_at_construction(self): with pytest.raises(ValueError, match="Unknown sharing_scope"): WorkqueueResourceOptions(sharing_scope="bogus") def test_configure_concurrency_limit(self, wq_resource): wq_resource.configure(WorkqueueResourceOptions(concurrency_limit=4)) + assert wq_resource.concurrency_limit == 4 def test_configure_concurrency_and_scope(self, wq_resource): wq_resource.configure( From 2afae3f8986c67328ca54dbdd04c3bbe2c91daf1 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 02:09:03 +0000 Subject: [PATCH 02/18] cuda.core: fill in PR number in release-notes entry --- cuda_core/docs/source/release/1.1.0-notes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuda_core/docs/source/release/1.1.0-notes.rst b/cuda_core/docs/source/release/1.1.0-notes.rst index f699446d9bb..16e369d1b2a 100644 --- a/cuda_core/docs/source/release/1.1.0-notes.rst +++ b/cuda_core/docs/source/release/1.1.0-notes.rst @@ -117,7 +117,7 @@ New features :class:`~cuda.core.typing.WorkqueueSharingScopeType` StrEnum accepted by :attr:`WorkqueueResourceOptions.sharing_scope` in addition to raw strings. - (`#NNNN `__) + (`#2330 `__) Fixes and enhancements ---------------------- From a22005d396fd9ac6130aea4f7921dec7d852061e Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 02:13:09 +0000 Subject: [PATCH 03/18] cuda.core: drop TYPE_CHECKING Device import to satisfy cython-lint The lazy import inside WorkqueueResource.device already imports Device at call time; the top-level TYPE_CHECKING import was unused as far as cython-lint could see and blocked pre-commit. --- cuda_core/cuda/core/_device_resources.pyi | 1 - cuda_core/cuda/core/_device_resources.pyx | 1 - 2 files changed, 2 deletions(-) diff --git a/cuda_core/cuda/core/_device_resources.pyi b/cuda_core/cuda/core/_device_resources.pyi index 2a0d040da9e..2ac6ca91368 100644 --- a/cuda_core/cuda/core/_device_resources.pyi +++ b/cuda_core/cuda/core/_device_resources.pyi @@ -5,7 +5,6 @@ from __future__ import annotations from collections.abc import Sequence as SequenceABC from dataclasses import dataclass -from cuda.core._device import Device from cuda.core.typing import WorkqueueSharingScopeType diff --git a/cuda_core/cuda/core/_device_resources.pyx b/cuda_core/cuda/core/_device_resources.pyx index 105da07af63..50b9d9ff12a 100644 --- a/cuda_core/cuda/core/_device_resources.pyx +++ b/cuda_core/cuda/core/_device_resources.pyx @@ -9,7 +9,6 @@ from dataclasses import dataclass from typing import TYPE_CHECKING if TYPE_CHECKING: - from cuda.core._device import Device from cuda.core.typing import WorkqueueSharingScopeType from libc.stdint cimport intptr_t From 08a64190903faf8145958f9e928de51f2efb88b1 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 02:17:17 +0000 Subject: [PATCH 04/18] cuda.core: fold #2329 + #2330 release notes; parametrize enum test; add 2-GPU device check - Merge the two 1.1.0 workqueue entries into one bullet crediting both PRs. - Parametrize test_configure_scope_with_enum over both WorkqueueSharingScopeType members. - Add test_device_id_matches_source_multi_gpu verifying WorkqueueResource.device.device_id tracks the source device when the caller switches devices. Uses the established system.get_num_devices() < 2 skip pattern. --- cuda_core/docs/source/release/1.1.0-notes.rst | 19 +++++++------- cuda_core/tests/test_green_context.py | 25 ++++++++++++++++--- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/cuda_core/docs/source/release/1.1.0-notes.rst b/cuda_core/docs/source/release/1.1.0-notes.rst index 16e369d1b2a..2a282904986 100644 --- a/cuda_core/docs/source/release/1.1.0-notes.rst +++ b/cuda_core/docs/source/release/1.1.0-notes.rst @@ -106,18 +106,19 @@ New features (`#2068 `__, closes `#2049 `__) -- Added ``concurrency_limit`` to :class:`WorkqueueResourceOptions` to - configure the expected maximum concurrent stream-ordered workloads. - (`#2329 `__) - -- Added read-only :attr:`WorkqueueResource.sharing_scope`, +- Extended :class:`WorkqueueResource` and :class:`WorkqueueResourceOptions` + to cover the full driver-side workqueue-config surface. Added + ``concurrency_limit`` to :class:`WorkqueueResourceOptions` for + configuring the expected maximum concurrent stream-ordered workloads, + and read-only :attr:`WorkqueueResource.sharing_scope`, :attr:`~WorkqueueResource.concurrency_limit`, and :attr:`~WorkqueueResource.device` properties for round-tripping the - driver-populated workqueue config. Added + driver-populated values. Added :class:`~cuda.core.typing.WorkqueueSharingScopeType` StrEnum accepted - by :attr:`WorkqueueResourceOptions.sharing_scope` in addition to - raw strings. - (`#2330 `__) + by :attr:`WorkqueueResourceOptions.sharing_scope` in addition to raw + strings. + (`#2329 `__, + `#2330 `__) Fixes and enhancements ---------------------- diff --git a/cuda_core/tests/test_green_context.py b/cuda_core/tests/test_green_context.py index 64022b233e3..2a1c1366d18 100644 --- a/cuda_core/tests/test_green_context.py +++ b/cuda_core/tests/test_green_context.py @@ -220,9 +220,28 @@ def test_configure_none_is_noop(self, wq_resource): def test_configure_valid_scope(self, wq_resource): wq_resource.configure(WorkqueueResourceOptions(sharing_scope="green_ctx_balanced")) - def test_configure_scope_with_enum(self, wq_resource): - wq_resource.configure(WorkqueueResourceOptions(sharing_scope=WorkqueueSharingScopeType.GREEN_CTX_BALANCED)) - assert wq_resource.sharing_scope is WorkqueueSharingScopeType.GREEN_CTX_BALANCED + @pytest.mark.parametrize("scope", list(WorkqueueSharingScopeType)) + def test_configure_scope_with_enum(self, wq_resource, scope): + wq_resource.configure(WorkqueueResourceOptions(sharing_scope=scope)) + assert wq_resource.sharing_scope is scope + + def test_device_id_matches_source_multi_gpu(self, init_cuda): + from cuda.core import Device, system + + if system.get_num_devices() < 2: + pytest.skip("requires 2+ GPUs") + dev0 = init_cuda + dev1 = Device(1) + dev1.set_current() + dev0.set_current() # restore, matches sample_device_alt pattern + try: + wq0 = dev0.resources.workqueue + wq1 = dev1.resources.workqueue + except (RuntimeError, ValueError, CUDAError) as exc: + pytest.skip(str(exc)) + assert wq0.device.device_id == dev0.device_id + assert wq1.device.device_id == dev1.device_id + assert wq0.device.device_id != wq1.device.device_id def test_invalid_scope_raises_at_construction(self): with pytest.raises(ValueError, match="Unknown sharing_scope"): From e4ebbba6d97a43891524e4aa4a87ad0b19198e8e Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 02:19:55 +0000 Subject: [PATCH 05/18] cuda.core tests: drop init_cuda from multi-GPU workqueue test --- cuda_core/tests/test_green_context.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cuda_core/tests/test_green_context.py b/cuda_core/tests/test_green_context.py index 2a1c1366d18..750fd5159b8 100644 --- a/cuda_core/tests/test_green_context.py +++ b/cuda_core/tests/test_green_context.py @@ -225,23 +225,22 @@ def test_configure_scope_with_enum(self, wq_resource, scope): wq_resource.configure(WorkqueueResourceOptions(sharing_scope=scope)) assert wq_resource.sharing_scope is scope - def test_device_id_matches_source_multi_gpu(self, init_cuda): + def test_device_id_matches_source_multi_gpu(self): from cuda.core import Device, system if system.get_num_devices() < 2: pytest.skip("requires 2+ GPUs") - dev0 = init_cuda + dev0 = Device(0) dev1 = Device(1) dev1.set_current() - dev0.set_current() # restore, matches sample_device_alt pattern + dev0.set_current() try: wq0 = dev0.resources.workqueue wq1 = dev1.resources.workqueue except (RuntimeError, ValueError, CUDAError) as exc: pytest.skip(str(exc)) - assert wq0.device.device_id == dev0.device_id - assert wq1.device.device_id == dev1.device_id - assert wq0.device.device_id != wq1.device.device_id + assert wq0.device.device_id == 0 + assert wq1.device.device_id == 1 def test_invalid_scope_raises_at_construction(self): with pytest.raises(ValueError, match="Unknown sharing_scope"): From 1c3ceb7723faa6f8e1d0083da09c7264b81436de Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 02:23:49 +0000 Subject: [PATCH 06/18] cuda.core tests: drop unnecessary set_current calls in multi-GPU workqueue test cuDeviceGetDevResource doesn't require the device to be current; verified locally that cuCtxGetCurrent returns the same context before and after the test body. --- cuda_core/tests/test_green_context.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cuda_core/tests/test_green_context.py b/cuda_core/tests/test_green_context.py index 750fd5159b8..d84401bf9f1 100644 --- a/cuda_core/tests/test_green_context.py +++ b/cuda_core/tests/test_green_context.py @@ -232,8 +232,6 @@ def test_device_id_matches_source_multi_gpu(self): pytest.skip("requires 2+ GPUs") dev0 = Device(0) dev1 = Device(1) - dev1.set_current() - dev0.set_current() try: wq0 = dev0.resources.workqueue wq1 = dev1.resources.workqueue From 9092dc4acb29eb50ae61381d256f228ffe159020 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 02:30:26 +0000 Subject: [PATCH 07/18] cuda.core tests: extract shared _RESOURCE_UNAVAILABLE_ERRORS tuple with rationale --- cuda_core/tests/test_green_context.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/cuda_core/tests/test_green_context.py b/cuda_core/tests/test_green_context.py index d84401bf9f1..effa7167371 100644 --- a/cuda_core/tests/test_green_context.py +++ b/cuda_core/tests/test_green_context.py @@ -43,12 +43,23 @@ # --------------------------------------------------------------------------- +# Resource queries (dev.resources.sm, dev.resources.workqueue) can fail in +# three orthogonal ways when the resource type isn't supported here: +# * RuntimeError — cuda.core was built against CUDA bindings that don't +# expose the resource (e.g. WorkqueueResource on 12.x). +# * ValueError — the runtime driver version is too old to support the +# resource (green-context / workqueue support gates). +# * CUDAError — the driver rejected the specific device-level query. +# Skip on any of them. +_RESOURCE_UNAVAILABLE_ERRORS = (RuntimeError, ValueError, CUDAError) + + @pytest.fixture def sm_resource(init_cuda): """Query SM resources from the device, skip if unsupported.""" try: return init_cuda.resources.sm - except (RuntimeError, ValueError, CUDAError) as exc: + except _RESOURCE_UNAVAILABLE_ERRORS as exc: pytest.skip(str(exc)) @@ -57,7 +68,7 @@ def wq_resource(init_cuda): """Query workqueue resources from the device, skip if unsupported.""" try: return init_cuda.resources.workqueue - except (RuntimeError, ValueError, CUDAError) as exc: + except _RESOURCE_UNAVAILABLE_ERRORS as exc: pytest.skip(str(exc)) @@ -235,7 +246,7 @@ def test_device_id_matches_source_multi_gpu(self): try: wq0 = dev0.resources.workqueue wq1 = dev1.resources.workqueue - except (RuntimeError, ValueError, CUDAError) as exc: + except _RESOURCE_UNAVAILABLE_ERRORS as exc: pytest.skip(str(exc)) assert wq0.device.device_id == 0 assert wq1.device.device_id == 1 From aebf2713cd02165b8084885ea8a0048a86f858db Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 02:49:36 +0000 Subject: [PATCH 08/18] cuda.core: restore Device TYPE_CHECKING import with noqa mypy needs Device resolvable in the generated .pyi (WorkqueueResource.device returns 'Device' as a string forward reference); noqa: F401 keeps cython-lint from re-flagging it as unused. --- cuda_core/cuda/core/_device_resources.pyi | 1 + cuda_core/cuda/core/_device_resources.pyx | 1 + 2 files changed, 2 insertions(+) diff --git a/cuda_core/cuda/core/_device_resources.pyi b/cuda_core/cuda/core/_device_resources.pyi index 2ac6ca91368..2a0d040da9e 100644 --- a/cuda_core/cuda/core/_device_resources.pyi +++ b/cuda_core/cuda/core/_device_resources.pyi @@ -5,6 +5,7 @@ from __future__ import annotations from collections.abc import Sequence as SequenceABC from dataclasses import dataclass +from cuda.core._device import Device from cuda.core.typing import WorkqueueSharingScopeType diff --git a/cuda_core/cuda/core/_device_resources.pyx b/cuda_core/cuda/core/_device_resources.pyx index 50b9d9ff12a..8a8be234bc9 100644 --- a/cuda_core/cuda/core/_device_resources.pyx +++ b/cuda_core/cuda/core/_device_resources.pyx @@ -9,6 +9,7 @@ from dataclasses import dataclass from typing import TYPE_CHECKING if TYPE_CHECKING: + from cuda.core._device import Device # noqa: F401 (used in string annotation on WorkqueueResource.device) from cuda.core.typing import WorkqueueSharingScopeType from libc.stdint cimport intptr_t From cb15baf66a53f95ee707856090096769f3eb5abb Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 02:50:58 +0000 Subject: [PATCH 09/18] cuda.core: simplify noqa to bare form (cython-lint didn't parse the parenthetical) --- cuda_core/cuda/core/_device_resources.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuda_core/cuda/core/_device_resources.pyx b/cuda_core/cuda/core/_device_resources.pyx index 8a8be234bc9..42289e77a68 100644 --- a/cuda_core/cuda/core/_device_resources.pyx +++ b/cuda_core/cuda/core/_device_resources.pyx @@ -9,7 +9,7 @@ from dataclasses import dataclass from typing import TYPE_CHECKING if TYPE_CHECKING: - from cuda.core._device import Device # noqa: F401 (used in string annotation on WorkqueueResource.device) + from cuda.core._device import Device # noqa from cuda.core.typing import WorkqueueSharingScopeType from libc.stdint cimport intptr_t From 202959b089bfd799d6c2e28a0c9b72d41df16639 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 02:52:24 +0000 Subject: [PATCH 10/18] cuda.core: use bare Device annotation on WorkqueueResource.device cython-lint doesn't count string-quoted forward references as usage of the TYPE_CHECKING import. The bare form works because from __future__ import annotations makes it a string at runtime anyway (matches _stream.pyx pattern). --- cuda_core/cuda/core/_device_resources.pyi | 2 +- cuda_core/cuda/core/_device_resources.pyx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cuda_core/cuda/core/_device_resources.pyi b/cuda_core/cuda/core/_device_resources.pyi index 2a0d040da9e..313d2580690 100644 --- a/cuda_core/cuda/core/_device_resources.pyi +++ b/cuda_core/cuda/core/_device_resources.pyi @@ -155,7 +155,7 @@ class WorkqueueResource: """ @property - def device(self) -> 'Device': + def device(self) -> Device: """The :class:`~cuda.core.Device` this workqueue resource is available on.""" def configure(self, options: WorkqueueResourceOptions) -> None: diff --git a/cuda_core/cuda/core/_device_resources.pyx b/cuda_core/cuda/core/_device_resources.pyx index 42289e77a68..a50a0ba0e7d 100644 --- a/cuda_core/cuda/core/_device_resources.pyx +++ b/cuda_core/cuda/core/_device_resources.pyx @@ -9,7 +9,7 @@ from dataclasses import dataclass from typing import TYPE_CHECKING if TYPE_CHECKING: - from cuda.core._device import Device # noqa + from cuda.core._device import Device from cuda.core.typing import WorkqueueSharingScopeType from libc.stdint cimport intptr_t @@ -604,7 +604,7 @@ cdef class WorkqueueResource: ) @property - def device(self) -> "Device": + def device(self) -> Device: """The :class:`~cuda.core.Device` this workqueue resource is available on.""" IF CUDA_CORE_BUILD_MAJOR >= 13: from cuda.core._device import Device # avoid circular import From 0a1c7df2c4e66dc736ab5299bbd8f7ee5d621b13 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 03:36:01 +0000 Subject: [PATCH 11/18] cuda.core tests: register WorkqueueSharingScopeType in _CASES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test_all_str_enums_in_cases enforces that every StrEnum in cuda.core.typing is bound to a driver-side counterpart or explicitly marked unbound. WorkqueueSharingScopeType wraps CUdevWorkqueueConfigScope 1:1 — clean binding-coverage entry. --- cuda_core/tests/test_enum_coverage.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cuda_core/tests/test_enum_coverage.py b/cuda_core/tests/test_enum_coverage.py index 09c12bbaf52..0916ab525cd 100644 --- a/cuda_core/tests/test_enum_coverage.py +++ b/cuda_core/tests/test_enum_coverage.py @@ -117,6 +117,13 @@ set(), set(), ), + ( + driver.CUdevWorkqueueConfigScope, + cuda.core.typing.WorkqueueSharingScopeType, + None, + set(), + set(), + ), ] if system.CUDA_BINDINGS_NVML_IS_COMPATIBLE: From 8fd22bc52be92a416d857c30410a5c34d28c88f5 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 04:56:10 +0000 Subject: [PATCH 12/18] cuda.core tests: gate WorkqueueSharingScopeType binding entry on CUDA 13+ CUdevWorkqueueConfigScope doesn't exist in CUDA 12.x cuda_bindings, so importing test_enum_coverage crashed with AttributeError. Only register the binding-coverage entry when the driver exposes the enum; otherwise mark the wrapper as unbound so test_all_str_enums_in_cases still passes. Verified both paths locally (real CUDA 13 + delattr-simulated CUDA 12). --- cuda_core/tests/test_enum_coverage.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/cuda_core/tests/test_enum_coverage.py b/cuda_core/tests/test_enum_coverage.py index 0916ab525cd..76dabdaf7fa 100644 --- a/cuda_core/tests/test_enum_coverage.py +++ b/cuda_core/tests/test_enum_coverage.py @@ -117,13 +117,6 @@ set(), set(), ), - ( - driver.CUdevWorkqueueConfigScope, - cuda.core.typing.WorkqueueSharingScopeType, - None, - set(), - set(), - ), ] if system.CUDA_BINDINGS_NVML_IS_COMPATIBLE: @@ -317,6 +310,22 @@ } +# CUdevWorkqueueConfigScope only exists in CUDA 13+ bindings; on older builds +# WorkqueueSharingScopeType has no driver-side counterpart to check against. +if hasattr(driver, "CUdevWorkqueueConfigScope"): + _CASES.append( + ( + driver.CUdevWorkqueueConfigScope, + cuda.core.typing.WorkqueueSharingScopeType, + None, + set(), + set(), + ) + ) +else: + _UNBOUND_STR_ENUMS.add(cuda.core.typing.WorkqueueSharingScopeType) + + @pytest.mark.parametrize( "binding, str_enum, mapping, binding_unmapped, str_enum_unmapped", _CASES, From 106d5c12a62f68210ac2609f7fe5d9b260560f32 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 05:10:05 +0000 Subject: [PATCH 13/18] cuda.core tests: sharpen CUDA-version boundary in WorkqueueSharingScopeType comment CUdevWorkqueueConfigScope landed in the driver in 13.1, not 13.0. Update the inline comment on the hasattr gate to reflect that the missing-driver-enum path covers cuda-bindings for both CUDA 12.x and CUDA 13.0.x. --- cuda_core/tests/test_enum_coverage.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cuda_core/tests/test_enum_coverage.py b/cuda_core/tests/test_enum_coverage.py index 76dabdaf7fa..8de26b25d4b 100644 --- a/cuda_core/tests/test_enum_coverage.py +++ b/cuda_core/tests/test_enum_coverage.py @@ -310,8 +310,10 @@ } -# CUdevWorkqueueConfigScope only exists in CUDA 13+ bindings; on older builds -# WorkqueueSharingScopeType has no driver-side counterpart to check against. +# CUdevWorkqueueConfigScope was added to the CUDA driver in 13.1 (missing +# from the 13.0.0 cuda.h and earlier); on cuda-bindings for CUDA 12.x or +# 13.0.x, WorkqueueSharingScopeType has no driver-side counterpart to +# check against. if hasattr(driver, "CUdevWorkqueueConfigScope"): _CASES.append( ( From be917b62399f573e047038145f8622bf65f79d6e Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 16:07:38 +0000 Subject: [PATCH 14/18] cuda.core: apply Mike's suggestion for WorkqueueResourceOptions.sharing_scope docstring --- cuda_core/cuda/core/_device_resources.pyi | 8 ++------ cuda_core/cuda/core/_device_resources.pyx | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/cuda_core/cuda/core/_device_resources.pyi b/cuda_core/cuda/core/_device_resources.pyi index 313d2580690..3b974ea4b68 100644 --- a/cuda_core/cuda/core/_device_resources.pyi +++ b/cuda_core/cuda/core/_device_resources.pyi @@ -48,12 +48,8 @@ class WorkqueueResourceOptions: Attributes ---------- sharing_scope : :class:`~cuda.core.typing.WorkqueueSharingScopeType`, optional - Workqueue sharing scope. Accepted values: - :attr:`~cuda.core.typing.WorkqueueSharingScopeType.DEVICE_CTX` or - :attr:`~cuda.core.typing.WorkqueueSharingScopeType.GREEN_CTX_BALANCED`. - Raw strings equal to the enum member values (``"device_ctx"``, - ``"green_ctx_balanced"``) are accepted at runtime for backward - compatibility. (Default to ``None``) + Workqueue sharing scope. Accepted values: ``"device_ctx"`` or + ``"green_ctx_balanced"``. concurrency_limit : int, optional Expected maximum number of concurrent stream-ordered workloads. Must be ``>= 1`` when set. The effective diff --git a/cuda_core/cuda/core/_device_resources.pyx b/cuda_core/cuda/core/_device_resources.pyx index a50a0ba0e7d..0d665f481e3 100644 --- a/cuda_core/cuda/core/_device_resources.pyx +++ b/cuda_core/cuda/core/_device_resources.pyx @@ -132,12 +132,8 @@ cdef class WorkqueueResourceOptions: Attributes ---------- sharing_scope : :class:`~cuda.core.typing.WorkqueueSharingScopeType`, optional - Workqueue sharing scope. Accepted values: - :attr:`~cuda.core.typing.WorkqueueSharingScopeType.DEVICE_CTX` or - :attr:`~cuda.core.typing.WorkqueueSharingScopeType.GREEN_CTX_BALANCED`. - Raw strings equal to the enum member values (``"device_ctx"``, - ``"green_ctx_balanced"``) are accepted at runtime for backward - compatibility. (Default to ``None``) + Workqueue sharing scope. Accepted values: ``"device_ctx"`` or + ``"green_ctx_balanced"``. concurrency_limit : int, optional Expected maximum number of concurrent stream-ordered workloads. Must be ``>= 1`` when set. The effective From a9939b5b77a6134b35652ff072d63eb3ccdada07 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 12:19:50 -0400 Subject: [PATCH 15/18] fix typing Co-authored-by: Michael Droettboom --- cuda_core/cuda/core/_device_resources.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuda_core/cuda/core/_device_resources.pyx b/cuda_core/cuda/core/_device_resources.pyx index 0d665f481e3..7c1dcf528bf 100644 --- a/cuda_core/cuda/core/_device_resources.pyx +++ b/cuda_core/cuda/core/_device_resources.pyx @@ -143,7 +143,7 @@ cdef class WorkqueueResourceOptions: submission remains non-overlapping. (Default to ``None``) """ - sharing_scope: WorkqueueSharingScopeType | None = None + sharing_scope: WorkqueueSharingScopeType | str | None = None concurrency_limit: int | None = None def __post_init__(self): From 37483ae7b6047fbeae5d7701e776dc9cd7c04db5 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 12:21:19 -0400 Subject: [PATCH 16/18] Update _device_resources.pyi --- cuda_core/cuda/core/_device_resources.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cuda_core/cuda/core/_device_resources.pyi b/cuda_core/cuda/core/_device_resources.pyi index 3b974ea4b68..ae2ce32704a 100644 --- a/cuda_core/cuda/core/_device_resources.pyi +++ b/cuda_core/cuda/core/_device_resources.pyi @@ -58,7 +58,7 @@ class WorkqueueResourceOptions: this cap, but the driver will not guarantee that work submission remains non-overlapping. (Default to ``None``) """ - sharing_scope: WorkqueueSharingScopeType | None = None + sharing_scope: WorkqueueSharingScopeType | str | None = None concurrency_limit: int | None = None def __post_init__(self): @@ -184,4 +184,4 @@ class DeviceResources: @property def workqueue(self) -> WorkqueueResource: """Return the :obj:`WorkqueueResource` for this device or context.""" -__all__ = ['DeviceResources', 'SMResource', 'SMResourceOptions', 'WorkqueueResource', 'WorkqueueResourceOptions'] \ No newline at end of file +__all__ = ['DeviceResources', 'SMResource', 'SMResourceOptions', 'WorkqueueResource', 'WorkqueueResourceOptions'] From ccb50cc8044b7fd48a90ef913db0cdaa9d5dda72 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 16:24:13 +0000 Subject: [PATCH 17/18] cuda.core: regenerate .pyi to match stubgen-pyx output end-of-file-fixer excludes .pyi (per .pre-commit-config.yaml), so the trailing newline manually added in the previous commit made stubgen-pyx flag the file every run. Reverting to the newline-less form stubgen emits. --- cuda_core/cuda/core/_device_resources.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuda_core/cuda/core/_device_resources.pyi b/cuda_core/cuda/core/_device_resources.pyi index ae2ce32704a..a19532dd7c1 100644 --- a/cuda_core/cuda/core/_device_resources.pyi +++ b/cuda_core/cuda/core/_device_resources.pyi @@ -184,4 +184,4 @@ class DeviceResources: @property def workqueue(self) -> WorkqueueResource: """Return the :obj:`WorkqueueResource` for this device or context.""" -__all__ = ['DeviceResources', 'SMResource', 'SMResourceOptions', 'WorkqueueResource', 'WorkqueueResourceOptions'] +__all__ = ['DeviceResources', 'SMResource', 'SMResourceOptions', 'WorkqueueResource', 'WorkqueueResourceOptions'] \ No newline at end of file From 119238b19bd811ba8e816488f8c871125662f8f6 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Thu, 9 Jul 2026 14:45:07 -0400 Subject: [PATCH 18/18] Apply suggestions from code review Co-authored-by: Michael Droettboom --- cuda_core/cuda/core/_device_resources.pyi | 2 +- cuda_core/cuda/core/_device_resources.pyx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cuda_core/cuda/core/_device_resources.pyi b/cuda_core/cuda/core/_device_resources.pyi index a19532dd7c1..7514f5a2f43 100644 --- a/cuda_core/cuda/core/_device_resources.pyi +++ b/cuda_core/cuda/core/_device_resources.pyi @@ -47,7 +47,7 @@ class WorkqueueResourceOptions: Attributes ---------- - sharing_scope : :class:`~cuda.core.typing.WorkqueueSharingScopeType`, optional + sharing_scope : :class:`~cuda.core.typing.WorkqueueSharingScopeType` | str, optional Workqueue sharing scope. Accepted values: ``"device_ctx"`` or ``"green_ctx_balanced"``. concurrency_limit : int, optional diff --git a/cuda_core/cuda/core/_device_resources.pyx b/cuda_core/cuda/core/_device_resources.pyx index 7c1dcf528bf..0c01956d2ea 100644 --- a/cuda_core/cuda/core/_device_resources.pyx +++ b/cuda_core/cuda/core/_device_resources.pyx @@ -131,7 +131,7 @@ cdef class WorkqueueResourceOptions: Attributes ---------- - sharing_scope : :class:`~cuda.core.typing.WorkqueueSharingScopeType`, optional + sharing_scope : :class:`~cuda.core.typing.WorkqueueSharingScopeType` | str, optional Workqueue sharing scope. Accepted values: ``"device_ctx"`` or ``"green_ctx_balanced"``. concurrency_limit : int, optional