Skip to content

cuda.core: expose driver-populated fields on WorkqueueResource - #2330

Merged
leofang merged 18 commits into
NVIDIA:mainfrom
leofang:leof/wq-readonly-props
Jul 9, 2026
Merged

cuda.core: expose driver-populated fields on WorkqueueResource#2330
leofang merged 18 commits into
NVIDIA:mainfrom
leofang:leof/wq-readonly-props

Conversation

@leofang

Copy link
Copy Markdown
Member

Summary

Add read-only :attr:sharing_scope, :attr:concurrency_limit, and :attr:device properties on WorkqueueResource so users can inspect the driver-populated workqueue config without dropping to raw cydriver. Also adds WorkqueueSharingScopeType StrEnum in cuda.core.typing for a typed return; raw strings matching the enum member values remain accepted at runtime for backward compatibility.

Follows section 5(d) — "Resources should be opaque but round-trippable" — from the green ctx design doc. That principle was written into SMResource (which exposes sm_count, min_partition_size, etc.) but not applied to WorkqueueResource — this PR closes that asymmetry.

Rationale

Before this change, dev.resources.workqueue returned an object whose driver-populated fields (sharingScope, wqConcurrencyLimit, device) were only reachable by:

  • ctypes.cast-ing the raw handle pointer back to a CUdevResource* and reading the struct manually, or
  • Re-issuing cuDeviceGetDevResource via cuda.bindings.cydriver.

Both routes require users to touch the driver ABI that cuda.core exists to hide.

API surface

wq=dev.resources.workqueuewq.sharing_scope# -> WorkqueueSharingScopeType (StrEnum, str-compatible)wq.concurrency_limit# -> int (driver cap, typically CUDA_DEVICE_MAX_CONNECTIONS)wq.device# -> cuda.core.Device# Configure still accepts raw strings (backward compatible)wq.configure(WorkqueueResourceOptions(sharing_scope=\"green_ctx_balanced\"))
# ...or the new StrEnumfromcuda.core.typingimportWorkqueueSharingScopeTypewq.configure(WorkqueueResourceOptions(
sharing_scope=WorkqueueSharingScopeType.GREEN_CTX_BALANCED,
concurrency_limit=4,
))

The WorkqueueResourceOptions.sharing_scope type annotation is now WorkqueueSharingScopeType | None (was str | None). Since 1.1.0 hasn't shipped yet this is a pre-release refactor; runtime behavior is preserved (StrEnum members are str-equal to their value).

Test coverage

Extended existing TestWorkqueueResource tests without touching the ones that exercise raw-string inputs (to preserve visible string-input coverage):

  • test_query — now also asserts isinstance(wq.sharing_scope, WorkqueueSharingScopeType), wq.concurrency_limit >= 1, wq.device.device_id == init_cuda.device_id.
  • test_configure_concurrency_limit — now round-trips concurrency_limit == 4 via the new property.
  • Added test_configure_scope_with_enum — configures via WorkqueueSharingScopeType.GREEN_CTX_BALANCED, verifies the property returns that same enum member.
  • Left alone: test_configure_valid_scope, test_configure_concurrency_and_scope, test_invalid_scope_raises_at_construction, both _raises_at_construction tests, test_configure_none_is_noop — these keep raw-string inputs exercised.

Full test_green_context.py locally: 36 passed, 2 skipped (arch), zero regressions.

Related

-- Leo's bot

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.
@copy-pr-bot

Copy link
Copy Markdown
Contributor

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actionsgithub-actionsBot added the cuda.core Everything related to the cuda.core module label Jul 9, 2026
@leofangleofang self-assigned this Jul 9, 2026
leofang added 8 commits July 9, 2026 02:13
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.
…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.
…queue test
cuDeviceGetDevResource doesn't require the device to be current; verified
locally that cuCtxGetCurrent returns the same context before and after
the test body.
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.
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).
@leofang

Copy link
Copy Markdown
MemberAuthor

/ok to test 202959b

@leofangleofang added triage Needs the team's attention feature New feature or request labels Jul 9, 2026
@leofang
leofang requested a review from Andy-JostJuly 9, 2026 02:59
@github-actions

This comment has been minimized.

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.
@leofang

Copy link
Copy Markdown
MemberAuthor

/ok to test 0a1c7df

leofang added 2 commits July 9, 2026 04:56
… 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).
…peType 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.
@leofang

Copy link
Copy Markdown
MemberAuthor

/ok to test 106d5c1

Comment threadcuda_core/cuda/core/_device_resources.pyi Outdated
Comment threadcuda_core/cuda/core/_device_resources.pyx Outdated
Comment threadcuda_core/cuda/core/_device_resources.pyx
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:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really should use the enum itself to validate the options (so we don't have the list of acceptable options duplicated all over the place). I thought it would be as easy as:

self.sharing_scope = WorkqueueSharingScopeType(self.sharing_scope)

which validates as excepted, but doesn't present the options.

I think we should add a "nice" enum validator and then do a sweep to use it everywhere (but outside of the scope for this PR).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel I am missing something. Maybe this comment makes perfect sense but is left at the wrong line? 😛

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, somehow it is at the wrong line. I was just pointing out that the validator here could just use the enum validator (so we don't have to duplicate the list of correct enum values every where that we validate them). We could almost do that now, but the error message wouldn't be as helpful. I'll work on that separately -- not worth fixing in this PR.

Comment on lines +579 to +582
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Could use a match statement here.

Comment threadcuda_core/docs/source/release/1.1.0-notes.rst
"""

sharing_scope: str | None = None
sharing_scope: WorkqueueSharingScopeType | None = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
sharing_scope: WorkqueueSharingScopeType |None=None
sharing_scope: WorkqueueSharingScopeType |str|None=None

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xref #2307 (comment).

@mdboom@Andy-Jost as per our discussion for #2248 on Tuesday, we decided to not widen the type annotation? Do I remember it correctly?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#2248 was for option classes, not enums. And this change is narrowing the type (so would be a breaking API change).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#2248 was for option classes, not enums.

Does it matter, though? This is still applied to the option class constructor.

And this change is narrowing the type (so would be a breaking API change).

Yes 😞 Alright.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really could use griffe to detect this breakage 🙂

@leofangleofang added this to the cuda.core v1.1.0 milestone Jul 9, 2026
@leofangleofang added P0 High priority - Must do! and removed triage Needs the team's attention labels Jul 9, 2026
@leofang
leofangforce-pushed the leof/wq-readonly-props branch from 8d50261 to be917b6CompareJuly 9, 2026 16:15
leofangand others added 3 commits July 9, 2026 12:19
Co-authored-by: Michael Droettboom <mdboom@gmail.com>
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.
@leofang
leofang marked this pull request as ready for review July 9, 2026 16:28
@leofang

Copy link
Copy Markdown
MemberAuthor

/ok to test ccb50cc

@leofang
leofang requested a review from mdboomJuly 9, 2026 16:28

@mdboommdboom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving, but we should make these two changes so we aren't narrowing the types in the docs.

Comment threadcuda_core/cuda/core/_device_resources.pyi Outdated
Comment threadcuda_core/cuda/core/_device_resources.pyx Outdated
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:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, somehow it is at the wrong line. I was just pointing out that the validator here could just use the enum validator (so we don't have to duplicate the list of correct enum values every where that we validate them). We could almost do that now, but the error message wouldn't be as helpful. I'll work on that separately -- not worth fixing in this PR.

@leofang

Copy link
Copy Markdown
MemberAuthor

Thanks, Mike! Since CI is almost green, what I will do is to wait the CI to finish, and then push the typing only changes to this PR, wait for the pre-commit CI to finish, and then admin merge.

Co-authored-by: Michael Droettboom <mdboom@gmail.com>
@leofang
leofang merged commit 52043f9 into NVIDIA:mainJul 9, 2026
3 checks passed
@github-actions

Copy link
Copy Markdown
Doc Preview CI
Preview removed because the pull request was closed or merged.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cuda.coreEverything related to the cuda.core modulefeatureNew feature or requestP0High priority - Must do!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@leofang@mdboom