Skip to content

Change: carry the wire Tensor as the remote-L3 per-argument record - #1756

Merged
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
YunjiQin:remote-l3-tensor-wire
Aug 10, 2026
Merged

Change: carry the wire Tensor as the remote-L3 per-argument record#1756
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
YunjiQin:remote-l3-tensor-wire

Conversation

@YunjiQin

Copy link
Copy Markdown
Contributor

The remote wire stops repacking what it already has

A remote L3 TASK frame carried a null-address ChipTensor per argument. The sender pulled
shape and dtype out of the Tensor it was already holding and repacked them; the session runner
rebuilt a ChipTensor from those bytes and immediately read the same two fields back out.
ChipTensor exists to carry a GM address (rule 13), and on this wire it never carried one — the
authoritative backing has always been the per-argument RemoteTensorDesc sidecar.

The record is now the wire Tensor itself, pushed verbatim:

// before — build_task_payload
ChipTensor meta{};                       // address deliberately null
meta.shape = ...; meta.dtype = ...;      // re-derived from ref
payload.args.tensor_metadata.push_back(meta);

// after
payload.args.tensors.push_back(ref);     // the Tensor the caller submitted

An argument bound for a remote worker is already the REMOTE_SIDECAR placeholder
TaskArgs.add_tensor builds, whose canonical identity names the remote backing. So nothing is
re-derived on either side, and the view's strides now cross where previously only shapes did.

PROTOCOL_VERSION 2 -> 3. Both ends of a run come from one pip install, so the constant is a
mismatch alarm at the frame header, not a dual-decode selector.

The wire only accepts a backing-free argument

encode_tensor / decode_tensor both reject backend_kind != REMOTE_SIDECAR, and
build_task_payload carries the encoder's own guard. Orchestrator::validate_remote_sidecars
already rejected a local backing alongside a sidecar at submit; these make it unrepresentable on
the wire as well.

Shapes and strides travel as ndims-many entries, so the slots past ndims that validate_tensor
requires be zero are never on the wire and cannot arrive dirty. decode_tensor runs
validate_tensor on every element and re-raises its invalid_argument as the codec's own error.

A 1-D record goes 44 -> 63 bytes; the general form is 55 + body_len + 8 * ndims. The growth is
the embedded BufferDescriptor (identity + backing properties) that makes the record
self-describing, plus the strides that were previously dropped.

Receiving side

_materialize_task_args takes the view from the wire Tensor verbatim and the backing from the
sidecar, then rebuilds a Tensor over a backing this runner holds. Two invariants it now checks,
both expressing that the sidecar is the sole authority for where the view sits:

  • desc.nbytes must equal the tensor's buffer.nbytes
  • the tensor's own byte_offset must be zero

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
  • cpput — 91/91
  • a2a3sim / a5sim full scene suites — rc=0, 0 failures on both
  • examples/workers/l4/vector_add_mixed_l3 on real a2a3 silicon, both halves:
    local max_diff=0.000e+00, remote max_diff=0.000e+00. This is the _st-pod.yml payload;
    a loopback daemon stood in for the second machine
  • pre-commit green

The sim, cpput and silicon runs above were taken on the immediately preceding base
(1f0f0060); pyut and pre-commit were re-run on this one. The rebase onto 3c69de1a was
conflict-free and git range-diff reports the patch byte-identical, so nothing in the delta
touches this path.

Context

Follows #1729, which flipped TaskArgs to carry the wire Tensor between local processes but
left the remote hop on the old per-argument record. Strides being flattened across a remote hop
predates both and is not addressed here.

@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: 5818317f-83cf-4d76-a6aa-e009007023a1

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

Remote L3 protocol version 3 replaces metadata-only task tensors with full REMOTE_SIDECAR Tensor descriptors. C++ encoding, Python decoding, session materialization, endpoint validation, design documentation, and tests now use the new representation.

Changes

Remote tensor wire transport

Layer / File(s) Summary
Version 3 tensor wire contract
src/common/hierarchical/remote_wire.h, src/common/hierarchical/remote_wire.cpp, python/simpler/remote_l3_protocol.py, docs/remote-l3-worker-design/protocol.md
The protocol now carries full Tensor records with buffer descriptors, view metadata, bounded descriptor bodies, and REMOTE_SIDECAR validation.
Remote TASK tensor transport
src/common/hierarchical/remote_endpoint.cpp, src/common/hierarchical/remote_wire.cpp, docs/remote-l3-worker-design/...
Remote TASK payloads now use args.tensors. Local backing and invalid tensor offsets are rejected.
Backing identity and tensor materialization
python/simpler/buffer.py, python/simpler/remote_l3_session.py, docs/remote-l3-worker-design/protocol.md
remote_backing_identity centralizes sidecar identities. The session rebuilds tensor views from validated descriptors and registered backing storage.
Wire and task-interface validation
tests/ut/cpp/hierarchical/test_remote_wire.cpp, tests/ut/py/test_task_interface.py, tests/ut/cpp/CMakeLists.txt, docs/remote-l3-worker-design/implementation-plan.md
Tests use remote-sidecar tensors and cover strided round trips, local-backing rejection, descriptor validation, and task materialization.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RemoteEndpoint
  participant RemoteWire
  participant RemoteL3Session
  participant sidecar_registry
  participant inner_worker.run
  RemoteEndpoint->>RemoteWire: encode args.tensors
  RemoteWire->>RemoteWire: validate REMOTE_SIDECAR descriptor
  RemoteWire->>RemoteL3Session: decode full Tensor
  RemoteL3Session->>sidecar_registry: resolve backing identity
  sidecar_registry-->>RemoteL3Session: return registered backing
  RemoteL3Session->>inner_worker.run: pass reconstructed Tensor view
Loading

Possibly related PRs

Poem

A rabbit packs tensors, sidecars in line,
With strides and descriptors, all neatly defined.
No local addresses cross the wire tonight,
The registry restores each view just right.
Hop, hop—protocol three takes flight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: remote-L3 per-argument records now carry the wire Tensor directly.
Description check ✅ Passed The description directly explains the wire Tensor change, validation rules, materialization behavior, protocol update, and verification results.
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.

@YunjiQin
YunjiQin force-pushed the remote-l3-tensor-wire branch from 614f2cc to 28fd56d Compare August 10, 2026 06:05

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/common/hierarchical/remote_wire.cpp (1)

459-501: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Require a sidecar for every remote TASK tensor.

The endpoint can emit an absent sidecar for a non-DEVICE placeholder. The wire codec accepts that record. _materialize_task_args rejects it, so the task fails only after transport and decode.

  • src/common/hierarchical/remote_wire.cpp#L459-L501: reject absent sidecars during encoding and decoding.
  • src/common/hierarchical/remote_endpoint.cpp#L739-L758: require tensor_sidecar.present for every remote TASK tensor before building the payload.

Based on the supplied protocol design: every remote TASK tensor requires an authoritative sidecar descriptor.

🤖 Prompt for 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.

In `@src/common/hierarchical/remote_wire.cpp` around lines 459 - 501, Require an
authoritative sidecar for every remote TASK tensor: in
src/common/hierarchical/remote_wire.cpp:459-501, update encode_remote_task_args
and decode_remote_task_args to reject absent sidecars during both encoding and
decoding; in src/common/hierarchical/remote_endpoint.cpp:739-758, update the
remote TASK tensor payload-building path to require tensor_sidecar.present
before constructing the payload.
🤖 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 `@docs/remote-l3-worker-design/protocol.md`:
- Around line 186-200: Update docs/remote-l3-worker-design/protocol.md lines
186-200 to remove or explicitly mark the stale metadata-only TensorWire v1
description obsolete, and consistently identify the current full TensorWire v3
format with REMOTE_SIDECAR descriptors and strided views. Update
docs/remote-l3-worker-design/implementation-plan.md line 95 to replace the “Wire
data zero” requirement with rejection tests for local backing and non-zero byte
offsets.

In `@python/simpler/remote_l3_session.py`:
- Around line 601-619: In the tensor materialization loop, validate that each
placeholder tensor’s buffer has BackendKind.REMOTE_SIDECAR before resolving or
materializing its backing. Reject any local-backed tensor even when its sidecar
is valid, and add a negative test covering that programmatically constructed
input.

In `@src/common/hierarchical/remote_wire.cpp`:
- Around line 346-375: Reject non-zero tensor byte offsets at every wire
boundary: update encode_tensor in src/common/hierarchical/remote_wire.cpp (lines
346-375) to validate tensor.byte_offset before serialization, the corresponding
C++ decoder in src/common/hierarchical/remote_wire.cpp (lines 378-422) to reject
decoded offsets, and the Python decoder in python/simpler/remote_l3_protocol.py
(lines 447-483) to reject byte_offset values. Add encode and decode coverage for
non-zero offsets in tests/ut/cpp/hierarchical/test_remote_wire.cpp (lines
89-122), ensuring invalid offsets fail during codec validation rather than later
materialization.

---

Outside diff comments:
In `@src/common/hierarchical/remote_wire.cpp`:
- Around line 459-501: Require an authoritative sidecar for every remote TASK
tensor: in src/common/hierarchical/remote_wire.cpp:459-501, update
encode_remote_task_args and decode_remote_task_args to reject absent sidecars
during both encoding and decoding; in
src/common/hierarchical/remote_endpoint.cpp:739-758, update the remote TASK
tensor payload-building path to require tensor_sidecar.present before
constructing the payload.
🪄 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: dcca4f4e-8b78-44b2-bbc5-918b63905fcf

📥 Commits

Reviewing files that changed from the base of the PR and between a8d7ce1 and 28fd56d.

📒 Files selected for processing (12)
  • docs/remote-l3-worker-design/buffers-and-transports.md
  • docs/remote-l3-worker-design/implementation-plan.md
  • docs/remote-l3-worker-design/protocol.md
  • python/simpler/buffer.py
  • python/simpler/remote_l3_protocol.py
  • python/simpler/remote_l3_session.py
  • src/common/hierarchical/remote_endpoint.cpp
  • src/common/hierarchical/remote_wire.cpp
  • src/common/hierarchical/remote_wire.h
  • tests/ut/cpp/CMakeLists.txt
  • tests/ut/cpp/hierarchical/test_remote_wire.cpp
  • tests/ut/py/test_task_interface.py

Comment thread docs/remote-l3-worker-design/protocol.md
Comment thread python/simpler/remote_l3_session.py
Comment thread src/common/hierarchical/remote_wire.cpp
@YunjiQin
YunjiQin force-pushed the remote-l3-tensor-wire branch from 28fd56d to f2577d2 Compare August 10, 2026 07:46
@YunjiQin

Copy link
Copy Markdown
Contributor Author

@coderabbitai the outside-diff finding ("Require a sidecar for every remote TASK tensor") is fixed at the endpoint, and I left the codec alone — here is why the split.

RemoteL3Endpoint::build_task_payload required tensor_sidecar.present only when address_space == DEVICE, so a HOST-space REMOTE_SIDECAR placeholder with an absent sidecar encoded fine and failed only in _materialize_task_args, after transport and decode. That check is now unconditional. It accepts exactly the same set of frames as before — the receiving side already required a sidecar for every argument — so the only change is where the failure lands.

The codec keeps the optional-sidecar encoding, because OptionalRemoteTensorDescWire is the wire's own shape and the sender is the layer that knows an argument was submitted without one. Moving the requirement into encode_remote_task_args would make the wire unable to represent a state the endpoint is the right place to refuse.

Covered by RemoteEndpoint.SidecarFreePlaceholderIsRejectedAtSubmission in tests/ut/cpp/hierarchical/test_remote_endpoint.cpp, matched on the message rather than a bare EXPECT_THROW (the surrounding tests do the same, since submit_progress has several other runtime_error paths). Verified it fails without the change.

The three inline threads are answered and resolved: two fixed, one skipped with rationale.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@YunjiQin The validation split is correct.

RemoteL3Endpoint::build_task_payload is the correct boundary to reject a submitted remote TASK argument without a sidecar. The unconditional tensor_sidecar.present check prevents the transport and decode round trip for an invalid submission.

Keeping OptionalRemoteTensorDescWire optional in the codec is also correct. The codec represents the wire structure. The endpoint enforces the submission contract.

The new RemoteEndpoint.SidecarFreePlaceholderIsRejectedAtSubmission test covers the required failure point and error-path specificity. No codec change is required for this finding.

🐇


✏️ Learnings added
Learnt from: YunjiQin
URL: https://github.com/hw-native-sys/simpler/pull/1756

Timestamp: 2026-08-10T07:48:01.041Z
Learning: In the remote L3 TASK protocol, `OptionalRemoteTensorDescWire` remains optional at the codec layer because it represents the wire structure. `RemoteL3Endpoint::build_task_payload` is the submission validation boundary and must reject every remote TASK tensor with an absent `tensor_sidecar`, regardless of its address space. The receiver also requires a sidecar during `_materialize_task_args`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@YunjiQin
YunjiQin force-pushed the remote-l3-tensor-wire branch from f2577d2 to c303511 Compare August 10, 2026 08:04
The remote L3 TASK frame carried a null-address ChipTensor per argument: the
sender stripped shape and dtype out of the Tensor it already held and repacked
them, and the session runner rebuilt a ChipTensor from them only to read those
two fields back out. ChipTensor exists to carry a GM address, and on this wire
it never did.

The record is now the wire Tensor itself. The sender pushes `a.tensor(i)`
verbatim; an argument bound for a remote worker is already the REMOTE_SIDECAR
placeholder `TaskArgs.add_tensor` built, whose identity names the remote
backing. Nothing is re-derived on either side, and the view's strides cross
where before only shapes did.

The sidecar stays the sole authority for an argument's backing, so a Tensor
with a local backing never crosses: `backend_kind` must be REMOTE_SIDECAR and
`byte_offset` must be zero, rejected on encode, on decode, and at
materialization. The sidecar must also be present for every argument, not only
a device-memory one -- an absent sidecar leaves the placeholder naming nothing
the runner could resolve, and the endpoint refuses it before transport rather
than letting it fail after decode. Orchestrator::validate_remote_sidecars
already refuses a local backing alongside a sidecar at submit; the codec and
the endpoint now close the same door.

`remote_backing_identity` becomes the single rule for naming a backing that
lives on another machine's worker, used by both the submitting L4's placeholder
and the importing session runner, where the two derived it separately before.

The per-argument record grows from a fixed 44 bytes to 55 + 8 * ndims (63 for a
1-D argument, 95 for a 5-D one); PROTOCOL_VERSION goes to 3, so a peer built
from a different install is refused at the frame header rather than misparsing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ChaoWao
ChaoWao merged commit c2236d9 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