Skip to content

Change: decode a chip child's mailbox blob once per dispatch - #1755

Merged
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
YunjiQin:blob-single-decode
Aug 10, 2026
Merged

ChaoWao merged 1 commit into
hw-native-sys:mainfrom
YunjiQin:blob-single-decode

Conversation

@YunjiQin

Copy link
Copy Markdown
Collaborator

One decode per dispatch

Both chip-child dispatch paths read the same mailbox bytes twice: once through
ImportRegistry.materialize_blob to reach each tensor's descriptor and build the identity ->
local-base map, then again through materialize_tensor_blob to produce the
ChipStorageTaskArgs the runtime ABI reads.

# before
resolved   = import_registry.materialize_blob(args_ptr, cap)     # decode #1
chip_args  = materialize_tensor_blob(args_ptr, cap, resolved)    # decode #2, same bytes

# after
args       = read_args_from_blob(args_ptr, cap)                  # the only decode
resolved   = import_registry.materialize_args(args)
chip_args  = materialize_task_args(args, resolved)

Per tensor that removes one 144 B copy and one full validate_tensor; at the 256-arg ceiling
(CHIP_MAX_TENSOR_ARGS) it is 36 KiB of copying plus 256 validations per dispatch.

No binding grows a parameter. read_args_from_blob and materialize_task_args both already
existed — the L2-leaf path runs this exact three-step shape today. materialize_tensor_blob is
deleted outright, and materialize_blob collapses into materialize_args, whose body it
duplicated except for the leading decode. Two functions out, none in.

Validation coverage is unchanged. TaskArgsView::tensors is the sole gate on a blob element,
and the surviving decode runs it over the same elements the deleted one did.

materialize_task_args is now the only path to the chip POD, so the resolved map's shape is
documented on it rather than by reference to a function that no longer exists.

Verification

  • Build green — four arch x runtime trees plus the nanobind extension
  • pyut — 1304 passed, 6 skipped, identical to the base commit's own run
  • a2a3sim full scene suite — rc=0, 0 failures, including
    TestPostForkHostBufferZeroCopy (19.2 s), which exercises this path
  • onboard test_l3_tensor_dispatch on real a2a3 silicon — PASS, under a task-submit
    device lock. This is the end-to-end owner-writes-blob / chip-child-materializes case
  • pre-commit green
  • a5sim full scene suite — running locally at push time; CI covers it
  • Dispatch-latency comparison — not run. What this removes is one memcpy plus one validation
    per tensor, and the scene tests carry 3-5 tensors, so any delta would sit inside host
    dispatch noise. The case for the change is one fewer decode path and two fewer functions;
    a measurable win needs a large-arg-count workload, which none of the suites here is

The static check the change has to satisfy:

$ grep -rn "materialize_tensor_blob\|materialize_blob\b" --include=*.py --include=*.cpp .
$ grep -n "read_blob(" python/bindings/task_interface.cpp
2407:            TaskArgsView view = read_blob(...);   # read_args_from_blob, the one remaining caller

Context

Deferred from #1729 review item 6, and again by #1747 on the grounds that closing it would need
materialize_tensor_blob to take an already-parsed view — a signature change on a hot binding.
That turned out not to be the shape of the fix: the parsed-view consumer is materialize_task_args,
which already exists, so the hot path moves to it and the re-reading function is simply deleted.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 261732ec-a902-47b9-8d63-3d9e2c8d5eab

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR removes blob-based tensor materialization. Chip and pipelined task paths now decode TaskArgs, resolve descriptors through ImportRegistry.materialize_args, and build runtime arguments with materialize_task_args.

Changes

Task argument materialization

Layer / File(s) Summary
Materialization contract
python/bindings/task_interface.cpp, python/simpler/buffer.py
The exported materialize_tensor_blob helper is removed. materialize_args(args) now materializes supplied task arguments. materialize_task_args documents the supported conversion path.
Worker submission flow
python/simpler/worker.py, tests/st/a2a3/tensormap_and_ringbuffer/test_l3_tensor_dispatch.py
Chip and pipelined submissions decode TaskArgs, resolve tensor handles, and construct chip arguments through the updated APIs. The dispatch flow documentation reflects the new sequence.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TaskBlob
  participant ChipWorker
  participant ImportRegistry
  participant materialize_task_args
  TaskBlob->>ChipWorker: read_args_from_blob()
  ChipWorker->>ImportRegistry: materialize_args(args)
  ImportRegistry-->>ChipWorker: resolved identities and address spaces
  ChipWorker->>materialize_task_args: build runtime arguments
  materialize_task_args-->>ChipWorker: ChipStorageTaskArgs
Loading

Possibly related PRs

Poem

A rabbit hops through blobs no more,
TaskArgs now leads the way.
Handles resolve at ImportRegistry,
Then chip arguments take their shape.
Clean paths guide each task today.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the single-decode change, removed APIs, performance impact, validation, and verification results.
Title check ✅ Passed The title clearly and concisely states that chip-child mailbox blobs are decoded once per dispatch.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/bindings/task_interface.cpp`:
- Around line 2395-2401: Update the documentation at
python/bindings/task_interface.cpp:2395-2401 to describe materialize_task_args
as the sole TaskArgs-to-ChipStorageTaskArgs conversion path, without implying it
is the only way to construct ChipStorageTaskArgs. Update the mailbox description
at tests/st/a2a3/tensormap_and_ringbuffer/test_l3_tensor_dispatch.py:14-16 to
call the payload a TaskArgs blob and state that the child builds
ChipStorageTaskArgs.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ffd37bab-4fa3-4f42-bec3-a894a382db8b

📥 Commits

Reviewing files that changed from the base of the PR and between 3c69de1 and 3178779.

📒 Files selected for processing (4)
  • python/bindings/task_interface.cpp
  • python/simpler/buffer.py
  • python/simpler/worker.py
  • tests/st/a2a3/tensormap_and_ringbuffer/test_l3_tensor_dispatch.py

Comment thread python/bindings/task_interface.cpp
@YunjiQin
YunjiQin force-pushed the blob-single-decode branch from 3178779 to ab85729 Compare August 10, 2026 06:04
Both chip-child dispatch paths read the same mailbox bytes twice: once through
`ImportRegistry.materialize_blob` to reach each tensor's descriptor and build
the identity -> local-base map, then again through `materialize_tensor_blob` to
produce the `ChipStorageTaskArgs` the runtime ABI reads. Each element therefore
paid two 144 B copies and two full `validate_tensor` passes, and at the 256-arg
ceiling that is 36 KiB of copying plus 256 validations per dispatch.

The bytes now decode once, into the wire `TaskArgs`, and both the mapping pass
and the POD build read that object -- the three-step shape the L2 leaf already
uses. `read_args_from_blob` and `materialize_task_args` both predate this
change, so no binding grows a parameter; `materialize_tensor_blob` is deleted
and `materialize_blob` collapses into `materialize_args`, whose body it
duplicated except for the leading decode.

Validation coverage is unchanged: `TaskArgsView::tensors` is the sole gate on a
blob element and the surviving decode runs it over the same elements.

`materialize_task_args` is now the only path to the chip POD, so the `resolved`
map's shape is documented on it rather than by reference to the deleted
function.
@ChaoWao
ChaoWao merged commit bd5ecb5 into hw-native-sys:main Aug 10, 2026
19 checks passed
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.

2 participants