Skip to content
Merged
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
13 changes: 12 additions & 1 deletion cuda_core/cuda/core/_device_resources.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,19 @@ class WorkqueueResourceOptions:
sharing_scope : str, optional
Workqueue sharing scope. Accepted values: ``"device_ctx"``
or ``"green_ctx_balanced"``. (Default to ``None``)
concurrency_limit : int, optional
Expected maximum number of concurrent stream-ordered
workloads. Must be ``>= 1`` when set. The effective
driver-side cap is ``CUDA_DEVICE_MAX_CONNECTIONS``
(typically ``[1, 32]``); configurations may exceed
this cap, but the driver will not guarantee that work
submission remains non-overlapping. (Default to ``None``)
"""
sharing_scope: str | None = None
concurrency_limit: int | None = None

def __post_init__(self):
...

class SMResource:
"""Represent an SM (streaming multiprocessor) resource partition.
Expand Down Expand Up @@ -120,7 +131,7 @@ class WorkqueueResource:
Parameters
----------
options : :obj:`WorkqueueResourceOptions`
Configuration options (sharing scope, etc.).
Configuration options (sharing scope, concurrency limit).
"""

class DeviceResources:
Expand Down
32 changes: 25 additions & 7 deletions cuda_core/cuda/core/_device_resources.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,28 @@ cdef class WorkqueueResourceOptions:
sharing_scope : str, optional
Workqueue sharing scope. Accepted values: ``"device_ctx"``
or ``"green_ctx_balanced"``. (Default to ``None``)
concurrency_limit : int, optional
Expected maximum number of concurrent stream-ordered
workloads. Must be ``>= 1`` when set. The effective
driver-side cap is ``CUDA_DEVICE_MAX_CONNECTIONS``
(typically ``[1, 32]``); configurations may exceed
this cap, but the driver will not guarantee that work
submission remains non-overlapping. (Default to ``None``)
"""

sharing_scope: str | None = None
concurrency_limit: int | None = None

def __post_init__(self):
if self.sharing_scope not in (None, "device_ctx", "green_ctx_balanced"):
raise ValueError(
f"Unknown sharing_scope: {self.sharing_scope!r}. "
"Expected 'device_ctx' or 'green_ctx_balanced'."
)
if self.concurrency_limit is not None and self.concurrency_limit < 1:
raise ValueError(
f"concurrency_limit must be >= 1, got {self.concurrency_limit}"
)


cdef inline int _validate_split_field_length(
Expand Down Expand Up @@ -541,17 +560,21 @@ cdef class WorkqueueResource:
Parameters
----------
options : :obj:`WorkqueueResourceOptions`
Configuration options (sharing scope, etc.).
Configuration options (sharing scope, concurrency limit).
"""
cdef WorkqueueResourceOptions opts = check_or_create_options(
WorkqueueResourceOptions, options, "Workqueue resource options"
)
_check_green_ctx_support()
_check_workqueue_support()
if opts.sharing_scope is None:
if opts.sharing_scope is None and opts.concurrency_limit is None:
return None

IF CUDA_CORE_BUILD_MAJOR >= 13:
if opts.concurrency_limit is not None:
self._wq_config_resource.wqConfig.wqConcurrencyLimit = (
<unsigned int>opts.concurrency_limit
)
if opts.sharing_scope == "device_ctx":
self._wq_config_resource.wqConfig.sharingScope = (
cydriver.CUdevWorkqueueConfigScope.CU_WORKQUEUE_SCOPE_DEVICE_CTX
Expand All @@ -560,11 +583,6 @@ cdef class WorkqueueResource:
self._wq_config_resource.wqConfig.sharingScope = (
cydriver.CUdevWorkqueueConfigScope.CU_WORKQUEUE_SCOPE_GREEN_CTX_BALANCED
)
else:
raise ValueError(
f"Unknown sharing_scope: {opts.sharing_scope!r}. "
"Expected 'device_ctx' or 'green_ctx_balanced'."
)
ELSE:
raise RuntimeError(
"WorkqueueResource requires cuda.core to be built with CUDA 13.x bindings"
Expand Down
4 changes: 4 additions & 0 deletions cuda_core/docs/source/release/1.1.0-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ New features
(`#2068 <https://github.com/NVIDIA/cuda-python/pull/2068>`__,
closes `#2049 <https://github.com/NVIDIA/cuda-python/issues/2049>`__)

- Added ``concurrency_limit`` to :class:`WorkqueueResourceOptions` to
configure the expected maximum concurrent stream-ordered workloads.
(`#2329 <https://github.com/NVIDIA/cuda-python/pull/2329>`__)

Fixes and enhancements
----------------------

Expand Down
31 changes: 28 additions & 3 deletions cuda_core/tests/test_green_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,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_invalid_scope_raises(self, wq_resource):
def test_invalid_scope_raises_at_construction(self):
with pytest.raises(ValueError, match="Unknown sharing_scope"):
wq_resource.configure(WorkqueueResourceOptions(sharing_scope="bogus"))
WorkqueueResourceOptions(sharing_scope="bogus")

def test_configure_concurrency_limit(self, wq_resource):
wq_resource.configure(WorkqueueResourceOptions(concurrency_limit=4))

def test_configure_concurrency_and_scope(self, wq_resource):
wq_resource.configure(
WorkqueueResourceOptions(
sharing_scope="green_ctx_balanced",
concurrency_limit=2,
)
)

def test_concurrency_limit_zero_raises_at_construction(self):
with pytest.raises(ValueError, match="concurrency_limit must be >= 1"):
WorkqueueResourceOptions(concurrency_limit=0)

def test_concurrency_limit_negative_raises_at_construction(self):
with pytest.raises(ValueError, match="concurrency_limit must be >= 1"):
WorkqueueResourceOptions(concurrency_limit=-3)


# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -495,9 +514,15 @@ def test_two_green_contexts_independent(self, init_cuda, sm_resource, fill_kerne
ctx_a.close()

def test_with_workqueue_resource(self, init_cuda, sm_resource, wq_resource, fill_kernel):
"""Green context with SM + workqueue resources can launch a kernel."""
"""Green context with SM + configured workqueue can launch a kernel."""
dev = init_cuda
groups, _ = sm_resource.split(SMResourceOptions(count=None))
wq_resource.configure(
WorkqueueResourceOptions(
sharing_scope="green_ctx_balanced",
concurrency_limit=4,
)
)

try:
ctx = dev.create_context(ContextOptions(resources=[groups[0], wq_resource]))
Expand Down