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

@leofang leofang commented Jul 9, 2026

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.workqueue

wq.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 StrEnum
from cuda.core.typing import WorkqueueSharingScopeType
wq.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-pr-bot Bot commented Jul 9, 2026

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-actions github-actions Bot added the cuda.core Everything related to the cuda.core module label Jul 9, 2026
@leofang leofang 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

leofang commented Jul 9, 2026

Copy link
Copy Markdown
Member Author

/ok to test 202959b

@leofang leofang added triage Needs the team's attention feature New feature or request labels Jul 9, 2026
@leofang leofang requested a review from Andy-Jost July 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

leofang commented Jul 9, 2026

Copy link
Copy Markdown
Member Author

/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

leofang commented Jul 9, 2026

Copy link
Copy Markdown
Member Author

/ok to test 106d5c1

Comment thread cuda_core/cuda/core/_device_resources.pyi Outdated
Comment thread cuda_core/cuda/core/_device_resources.pyx Outdated
Comment thread cuda_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
Member Author

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 thread cuda_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
Member Author

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
Member Author

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
Member Author

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 🙂

@leofang leofang added this to the cuda.core v1.1.0 milestone Jul 9, 2026
@leofang leofang added P0 High priority - Must do! and removed triage Needs the team's attention labels Jul 9, 2026
@leofang leofang force-pushed the leof/wq-readonly-props branch from 8d50261 to be917b6 Compare July 9, 2026 16:15
leofang and 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

leofang commented Jul 9, 2026

Copy link
Copy Markdown
Member Author

/ok to test ccb50cc

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

@mdboom mdboom 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 thread cuda_core/cuda/core/_device_resources.pyi Outdated
Comment thread cuda_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

leofang commented Jul 9, 2026

Copy link
Copy Markdown
Member Author

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:main Jul 9, 2026
3 checks passed
@github-actions

github-actions Bot commented Jul 9, 2026

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

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

Labels

cuda.core Everything related to the cuda.core module feature New feature or request P0 High priority - Must do!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants