cuda.core: expose driver-populated fields on WorkqueueResource#2330
Conversation
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.
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).
|
/ok to test 202959b |
This comment has been minimized.
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.
|
/ok to test 0a1c7df |
… 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.
|
/ok to test 106d5c1 |
| 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: |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
I feel I am missing something. Maybe this comment makes perfect sense but is left at the wrong line? 😛
There was a problem hiding this comment.
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.
| 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 |
There was a problem hiding this comment.
nit: Could use a match statement here.
| """ | ||
|
|
||
| sharing_scope: str | None = None | ||
| sharing_scope: WorkqueueSharingScopeType | None = None |
There was a problem hiding this comment.
| sharing_scope: WorkqueueSharingScopeType | None = None | |
| sharing_scope: WorkqueueSharingScopeType | str | None = None |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
#2248 was for option classes, not enums. And this change is narrowing the type (so would be a breaking API change).
There was a problem hiding this comment.
#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.
There was a problem hiding this comment.
We really could use griffe to detect this breakage 🙂
…ng_scope docstring
8d50261 to
be917b6
Compare
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.
|
/ok to test ccb50cc |
mdboom
left a comment
There was a problem hiding this comment.
Approving, but we should make these two changes so we aren't narrowing the types in the docs.
| 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: |
There was a problem hiding this comment.
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.
|
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>
|
Summary
Add read-only :attr:
sharing_scope, :attr:concurrency_limit, and :attr:deviceproperties onWorkqueueResourceso users can inspect the driver-populated workqueue config without dropping to rawcydriver. Also addsWorkqueueSharingScopeTypeStrEnum incuda.core.typingfor 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 exposessm_count,min_partition_size, etc.) but not applied toWorkqueueResource— this PR closes that asymmetry.Rationale
Before this change,
dev.resources.workqueuereturned an object whose driver-populated fields (sharingScope,wqConcurrencyLimit,device) were only reachable by:ctypes.cast-ing the rawhandlepointer back to aCUdevResource*and reading the struct manually, orcuDeviceGetDevResourceviacuda.bindings.cydriver.Both routes require users to touch the driver ABI that
cuda.coreexists to hide.API surface
The
WorkqueueResourceOptions.sharing_scopetype annotation is nowWorkqueueSharingScopeType | None(wasstr | None). Since 1.1.0 hasn't shipped yet this is a pre-release refactor; runtime behavior is preserved (StrEnum members arestr-equal to their value).Test coverage
Extended existing
TestWorkqueueResourcetests without touching the ones that exercise raw-string inputs (to preserve visible string-input coverage):test_query— now also assertsisinstance(wq.sharing_scope, WorkqueueSharingScopeType),wq.concurrency_limit >= 1,wq.device.device_id == init_cuda.device_id.test_configure_concurrency_limit— now round-tripsconcurrency_limit == 4via the new property.test_configure_scope_with_enum— configures viaWorkqueueSharingScopeType.GREEN_CTX_BALANCED, verifies the property returns that same enum member.test_configure_valid_scope,test_configure_concurrency_and_scope,test_invalid_scope_raises_at_construction, both_raises_at_constructiontests,test_configure_none_is_noop— these keep raw-string inputs exercised.Full
test_green_context.pylocally: 36 passed, 2 skipped (arch), zero regressions.Related
concurrency_limitwrite-side).WorkqueueResource(per 5(d)) and the newWorkqueueSharingScopeTypeStrEnum.-- Leo's bot