Skip to content

Refactor: ask async-DMA provisioning for one flag, not a set of engines - #2089

Merged
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
ChaoWao:dma-workspace-flag
Sep 1, 2026
Merged

Refactor: ask async-DMA provisioning for one flag, not a set of engines#2089
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
ChaoWao:dma-workspace-flag

Conversation

@ChaoWao

@ChaoWao ChaoWao commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

simpler_provision_dma_workspace took a DmaWorkspaceKind bitmask, but nothing could ever set more than one bit in it — dma_workspace_supported_mask() names a single engine, and the only producer was a ternary over the enable_sdma bool the Python binding already had. This replaces the caller-supplied set with that bool and derives the mask inside DeviceRunnerBase.

Why a set was the wrong question. Selecting an engine is already the kernel's decision: get_dma_workspace(args, kind) reads whichever addresses were injected into GlobalContext, and a kind that was not provisioned reads back 0. What a caller needs to say is which engines it declines, and there is exactly one — SDMA, because its workspace cannot be obtained without also creating 48 CP-process STARS streams (SdmaWorkspaceManager::Init() builds the streams first, then makes the 16 KB workspace their descriptor table), and a Worker holding those gets a single device-reset attempt after an AICore fault instead of three. No other engine carries that cost, so no other engine should be conditional.

The mask survives only below the comm seam, where it addresses per-kind slots and is the right shape. DmaWorkspaceKind and dma_workspace_addr[KIND_COUNT] are untouched — those are what URMA will need.

A fail-fast that had to become explicit. Rejecting enable_sdma on a platform without SDMA used to fall out of the unsupported-bits test. A derived mask has no unsupported bits by construction, so a Worker opting in on sim / a5 / hbg would have silently degraded to an empty set and reached its first run reading a zero address. There is now a direct check, verified:

RuntimeError: async-DMA (SDMA) workspace provisioning failed with code -1001

A dormant guard on the seam. dma_workspace_provision() takes a set and returns one opaque handle; dma_workspace_release() recovers the concrete provider by casting it. Those agree only while ≤1 bit can be set — true today, false the day the supported mask widens for URMA, where a second engine would be released as the type of the first with no compile error and no runtime complaint. The check is deliberately unreachable now and arms itself exactly when the assumption expires.

API change

simpler_provision_dma_workspace's third parameter changes type (uint32_t required_maskint enable_sdma). This is runtime_c_api.h, so codestyle.md rule 10 Tier C applies — flagging it explicitly for maintainer review. The only consumer in-tree is chip_worker.cpp; git grep finds no other caller, and there is no cross-repo consumer of this entry point.

ChipWorker::init's async-DMA parameter changes in place (uint32_tbool) at the same position. test_pipeline_contract.cpp pins that signature against silent positional breakage and caught this; the alias is updated with the reason, since this retypes rather than reorders.

Testing

  • Full editable build (pip install --no-build-isolation -e .) — compiles the binding, chip_worker.cpp, both c_api_shared.cpp, device_runner_base.cpp
  • cpput 127/127 (ctest -LE requires_hardware -j4, CI's invocation)
  • pyut 2094 passed, 18 skipped
  • a2a3 onboard: examples/a2a3/tensormap_and_ringbuffer/prefetch_async_demo passes through task-submit — the case that actually provisions the workspace and runs the control-path warmup
  • enable_sdma=True on a2a3sim still raises rather than coming up unprovisioned
  • clang-format / check_headers / check_retired_names clean

Sim scene tests deselect on this box under --manual exclude, and would not exercise this anyway: on sim the entry point returns UNSUPPORTED/0 identically before and after. The onboard run above is the meaningful signal.

Docs for this subsystem are corrected separately in #2088 (file-disjoint, no dependency in either direction).

simpler_provision_dma_workspace took a DmaWorkspaceKind bitmask, but nothing
could ever set more than one bit in it: dma_workspace_supported_mask() names a
single engine, and the only producer was a ternary over the enable_sdma bool the
Python binding already had. The set was speculative generality standing in front
of a question nobody was asking.

Selecting an engine is not the runtime's decision to take. Kernels choose with
get_dma_workspace(args, kind) against every address that was injected, so what a
caller actually needs to say is which engines it declines to have provisioned —
and there is exactly one. SDMA is declinable because its workspace cannot be
obtained without also creating 48 CP-process STARS streams
(SdmaWorkspaceManager::Init builds the streams, then makes the 16 KB workspace
their descriptor table), and a Worker holding those gets one device-reset
attempt after an AICore fault instead of three. No other engine carries that, so
no other engine should be conditional.

Take a bool from the binding down to DeviceRunnerBase and derive the mask there
as supported-minus-declined. The mask survives only below the comm seam, where
it addresses per-kind slots and is the right shape.

Rejecting an unsatisfiable request has to become explicit. It used to fall out
of the unsupported-bits test; a derived mask has no unsupported bits by
construction, so a Worker opting into SDMA on sim/a5/hbg would have degraded
into an empty set and reached its first run reading a zero workspace address.
Check enable_sdma against the supported mask directly instead.

Guard the seam the derived mask now feeds. dma_workspace_provision() takes a set
and returns one opaque handle, and dma_workspace_release() recovers the concrete
provider by casting it; those agree only while at most one bit can be set. That
holds today and stops holding when the supported mask widens for URMA, where a
second engine would be released as the type of the first with no compile error
and no runtime complaint. The check is deliberately dormant now and arms itself
exactly when the assumption expires, so widening the mask yields a clear
rejection and points whoever widens it at the per-kind handle the seam still
needs.

The signature guard in test_pipeline_contract.cpp pins parameter order against
silent positional breakage. This retypes in place rather than moving, so the
alias records what changed and why.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 57 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 43a1df0b-3a81-4bd2-8307-9e0b4af37de2

📥 Commits

Reviewing files that changed from the base of the PR and between ae90918 and 515a851.

📒 Files selected for processing (10)
  • python/bindings/task_interface.cpp
  • src/common/platform/onboard/host/c_api_shared.cpp
  • src/common/platform/onboard/host/device_runner_base.cpp
  • src/common/platform/onboard/host/device_runner_base.h
  • src/common/platform/sim/host/c_api_shared.cpp
  • src/common/platform_comm/comm.h
  • src/common/worker/chip_worker.cpp
  • src/common/worker/chip_worker.h
  • src/common/worker/runtime_c_api.h
  • tests/ut/cpp/hierarchical/test_pipeline_contract.cpp

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ChaoWao
ChaoWao merged commit 55b7e0f into hw-native-sys:main Sep 1, 2026
20 checks passed
@ChaoWao
ChaoWao deleted the dma-workspace-flag branch September 1, 2026 12:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant