Skip to content

feat(a5): add URMA deferred completion backend for tensormap_and_ringbuffer - #1392

Merged
jvjhfhg merged 6 commits into
hw-native-sys:mainfrom
wxwnnzdyd:a5-urma-deferred-completion-clean
Jul 20, 2026
Merged

feat(a5): add URMA deferred completion backend for tensormap_and_ringbuffer#1392
jvjhfhg merged 6 commits into
hw-native-sys:mainfrom
wxwnnzdyd:a5-urma-deferred-completion-clean

Conversation

@wxwnnzdyd

Copy link
Copy Markdown
Contributor

Summary

  • Add AICore-side URMA async request submission for TGET/TPUT.
  • Register URMA async events as deferred completion tokens.
  • Add AICPU-side URMA CQ polling and task retirement.
  • Wire URMA completion type through the existing async wait framework.
  • Initialize PTO-ISA URMA workspace in A5 onboard host communication setup.

Testing

  • Real A5 deferred demo validated manually on devices 0,1.
  • git diff --check

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change adds URMA communication workspace management, asynchronous TGET/TPUT submission, event-handle polling, backend-cookie propagation through completion queues, and architecture-specific host build configuration.

Changes

URMA completion integration

Layer / File(s) Summary
Host build and Ascend linkage
src/a5/platform/onboard/host/CMakeLists.txt
Requires PTO ISA headers, adds architecture-specific Ascend include and library paths, supports HCCL/HCOMM discovery, adds runtime link dependencies, and exposes SIMPLER_PTO_ISA_BUILD_COMMIT.
URMA workspace provisioning
src/a5/platform/onboard/host/comm_hccl.cpp
Allocates base and dense-prefix per-domain URMA workspaces, assigns them to communication contexts, synchronizes initialization, and resets them across cleanup paths.
URMA request submission and event registration
src/a5/runtime/tensormap_and_ringbuffer/runtime/backend/urma/urma_completion_kernel.h
Defines URMA request descriptors and TGET/TPUT helpers, chunks large transfers, submits asynchronous events, and records completion metadata.
URMA completion polling
src/a5/runtime/tensormap_and_ringbuffer/runtime/backend/urma/urma_completion_scheduler.h
Defines URMA context layouts and event-handle helpers, validates CQ/WQ state, polls completion entries, and returns pending, ready, or failed results.
Backend cookie propagation and wait integration
src/a5/runtime/tensormap_and_ringbuffer/runtime/aicore_completion_mailbox*.h, src/a5/runtime/tensormap_and_ringbuffer/runtime/pto_async_*.h, src/a5/runtime/tensormap_and_ringbuffer/runtime/scheduler/scheduler_completion.cpp
Adds URMA completion typing and backend-cookie fields, propagates cookies through deferred entries and mailbox messages, and maps URMA conditions to polling operations.

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

Sequence Diagram(s)

sequenceDiagram
  participant URMARequest
  participant CompletionKernel
  participant CompletionMailbox
  participant AsyncWait
  participant URMAScheduler
  URMARequest->>CompletionKernel: submit TGET or TPUT
  CompletionKernel->>CompletionMailbox: register event handle and workspace cookie
  CompletionMailbox->>AsyncWait: drain completion condition
  AsyncWait->>URMAScheduler: poll event handle
  URMAScheduler-->>AsyncWait: PENDING, READY, or FAILED
Loading

Possibly related PRs

Poem

I’m a rabbit with URMA hops,
Carrying cookies through mailbox stops.
TGET and TPUT leap through the air,
CQ tails turn with careful care.
Workspaces bloom, then safely reset—
Async paths are ready yet!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly states the main change: adding a URMA deferred completion backend for tensormap_and_ringbuffer.
Description check ✅ Passed The description matches the PR objectives and summarizes the same URMA submission, polling, and workspace setup changes.

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.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces support for URMA (Ultra Remote Memory Access) workspaces and completions in the host runtime and tensormap/ringbuffer runtime. It adds URMA workspace management, a new URMA completion kernel and scheduler, and integrates a 'backend_cookie' field across completion mailbox messages and deferred entries to support URMA event handles. Additionally, the CMake configuration is updated to support newer CANN packages and architecture-specific paths. A bug was identified in the updated CMake library-finding logic where finding only 'libhccl' but not 'libhcomm' erroneously triggers a fatal error instead of falling back correctly.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/a5/platform/onboard/host/CMakeLists.txt Outdated

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

🤖 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 `@src/a5/platform/onboard/host/CMakeLists.txt`:
- Around line 187-192: Update the Ascend HCCL discovery conditional around
HCOMM_LIB to add a branch for HCCL_LIB when the preferred libhccl target is
unavailable. Set HCCL_LINK_TARGETS from HCCL_LIB and emit the appropriate
fallback warning, while retaining the existing HCOMM_LIB fallback and fatal
error only when neither library is found.

In `@src/a5/platform/onboard/host/comm_hccl.cpp`:
- Around line 1076-1085: Update the error paths in the domain allocation flow,
including the aclrtMalloc and aclrtMemcpy failure branches near
release_own_vmm_window, to call release_domain_peer_windows(*out) before
returning -1. Ensure peer-imported physical handles and virtual mappings are
released while preserving the existing cleanup operations.
- Around line 990-991: Update the domain workspace initialization near domain
context setup to use the explicitly configured sdma_workspace when SDMA is
enabled, rather than inheriting h->host_ctx.workSpace; ensure non-dense domains
receive no base URMA workspace while preserving the corresponding workspace size
behavior.

In
`@src/a5/runtime/tensormap_and_ringbuffer/runtime/backend/urma/urma_completion_kernel.h`:
- Around line 202-212: Update submit_chunked_urma_request to validate that
desc.src and desc.dst have equal logical element counts before calculating
total_bytes or submitting any transfer. On mismatch, defer
PTO2_ERROR_ASYNC_COMPLETION_INVALID through ctx and return false; preserve the
existing contiguous 1D validation and transfer flow for matching lengths.
- Around line 191-193: Update submit_urma_request_once() to propagate a false
result from register_urma_async_event() instead of unconditionally returning
true. On registration failure, drain the event before returning false so the DMA
is not left untracked and the chunked submission loop stops; preserve
defer_flush() and the successful return path for successful registration.

In
`@src/a5/runtime/tensormap_and_ringbuffer/runtime/backend/urma/urma_completion_scheduler.h`:
- Around line 192-201: Update the CQE processing loop so a failed completion is
consumed before returning failure: advance next_tail past the failed CQE and
call update_tail_info with the new tail before returning
CompletionPollState::FAILED. Preserve the existing failure status and
successful-CQE handling.
- Around line 141-159: Update the cache invalidation in the completion-context
setup around UrmaCqCtx and UrmaWqCtx so it covers every cache line spanned by
each context, not only the line containing its first byte. Use the actual
sizeof(UrmaCqCtx) and sizeof(UrmaWqCtx) ranges when calling
cache_invalidate_range, while preserving the existing cache_line alignment and
pointer calculations.
🪄 Autofix (Beta)

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

Run ID: b6541b26-b476-410a-a953-92cab3fbcab4

📥 Commits

Reviewing files that changed from the base of the PR and between 4a803de and e5be256.

📒 Files selected for processing (9)
  • src/a5/platform/onboard/host/CMakeLists.txt
  • src/a5/platform/onboard/host/comm_hccl.cpp
  • src/a5/runtime/tensormap_and_ringbuffer/runtime/aicore_completion_mailbox.h
  • src/a5/runtime/tensormap_and_ringbuffer/runtime/aicore_completion_mailbox_types.h
  • src/a5/runtime/tensormap_and_ringbuffer/runtime/backend/urma/urma_completion_kernel.h
  • src/a5/runtime/tensormap_and_ringbuffer/runtime/backend/urma/urma_completion_scheduler.h
  • src/a5/runtime/tensormap_and_ringbuffer/runtime/pto_async_kernel_api.h
  • src/a5/runtime/tensormap_and_ringbuffer/runtime/pto_async_wait.h
  • src/a5/runtime/tensormap_and_ringbuffer/runtime/scheduler/scheduler_completion.cpp

Comment thread src/a5/platform/onboard/host/CMakeLists.txt Outdated
Comment thread src/a5/platform/onboard/host/comm_hccl.cpp Outdated
Comment thread src/a5/platform/onboard/host/comm_hccl.cpp Outdated
Comment on lines +202 to +212
inline __aicore__ bool submit_chunked_urma_request(AsyncCtx &ctx, UrmaRequestDescriptor<DstTensor, SrcTensor> desc) {
using RawDType = typename DstTensor::RawDType;
static_assert(std::is_same_v<RawDType, typename SrcTensor::RawDType>, "URMA transfer requires matching dtypes");

if (!is_flat_contiguous_1d(desc.dst) || !is_flat_contiguous_1d(desc.src)) {
pto2::detail::defer_error(ctx, PTO2_ERROR_ASYNC_COMPLETION_INVALID);
return false;
}

const uint64_t elem_count = tensor_element_count(desc.dst);
const uint64_t total_bytes = elem_count * sizeof(RawDType);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reject mismatched source and destination lengths.

Only desc.dst determines the transfer and slice length. A shorter source can therefore produce slices beyond its logical extent, while a longer source is silently truncated.

Proposed fix
-    const uint64_t elem_count = tensor_element_count(desc.dst);
+    const uint64_t elem_count = tensor_element_count(desc.dst);
+    if (elem_count != tensor_element_count(desc.src)) {
+        pto2::detail::defer_error(ctx, PTO2_ERROR_ASYNC_COMPLETION_INVALID);
+        return false;
+    }
     const uint64_t total_bytes = elem_count * sizeof(RawDType);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
inline __aicore__ bool submit_chunked_urma_request(AsyncCtx &ctx, UrmaRequestDescriptor<DstTensor, SrcTensor> desc) {
using RawDType = typename DstTensor::RawDType;
static_assert(std::is_same_v<RawDType, typename SrcTensor::RawDType>, "URMA transfer requires matching dtypes");
if (!is_flat_contiguous_1d(desc.dst) || !is_flat_contiguous_1d(desc.src)) {
pto2::detail::defer_error(ctx, PTO2_ERROR_ASYNC_COMPLETION_INVALID);
return false;
}
const uint64_t elem_count = tensor_element_count(desc.dst);
const uint64_t total_bytes = elem_count * sizeof(RawDType);
inline __aicore__ bool submit_chunked_urma_request(AsyncCtx &ctx, UrmaRequestDescriptor<DstTensor, SrcTensor> desc) {
using RawDType = typename DstTensor::RawDType;
static_assert(std::is_same_v<RawDType, typename SrcTensor::RawDType>, "URMA transfer requires matching dtypes");
if (!is_flat_contiguous_1d(desc.dst) || !is_flat_contiguous_1d(desc.src)) {
pto2::detail::defer_error(ctx, PTO2_ERROR_ASYNC_COMPLETION_INVALID);
return false;
}
const uint64_t elem_count = tensor_element_count(desc.dst);
if (elem_count != tensor_element_count(desc.src)) {
pto2::detail::defer_error(ctx, PTO2_ERROR_ASYNC_COMPLETION_INVALID);
return false;
}
const uint64_t total_bytes = elem_count * sizeof(RawDType);
🤖 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/a5/runtime/tensormap_and_ringbuffer/runtime/backend/urma/urma_completion_kernel.h`
around lines 202 - 212, Update submit_chunked_urma_request to validate that
desc.src and desc.dst have equal logical element counts before calculating
total_bytes or submitting any transfer. On mismatch, defer
PTO2_ERROR_ASYNC_COMPLETION_INVALID through ctx and return false; preserve the
existing contiguous 1D validation and transfer flow for matching lengths.

Comment on lines +192 to +201
const uint8_t substatus = static_cast<uint8_t>((dw0 >> 16) & 0xFFu);
const uint8_t status = static_cast<uint8_t>((dw0 >> 24) & 0xFFu);
if (status != 0 || substatus != 0) {
return {CompletionPollState::FAILED, PTO2_ERROR_ASYNC_COMPLETION_INVALID};
}
next_tail++;
}

if (next_tail != cur_tail) {
update_tail_info(cq_ctx, wq_ctx, next_tail);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Consume failed CQEs before returning failure.

The early return leaves cur_tail on the same failed CQE, causing every later poll on that CQ to encounter it again and preventing queue retirement.

Proposed fix
         const uint8_t substatus = static_cast<uint8_t>((dw0 >> 16) & 0xFFu);
         const uint8_t status = static_cast<uint8_t>((dw0 >> 24) & 0xFFu);
         if (status != 0 || substatus != 0) {
+            ++next_tail;
+            update_tail_info(cq_ctx, wq_ctx, next_tail);
             return {CompletionPollState::FAILED, PTO2_ERROR_ASYNC_COMPLETION_INVALID};
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const uint8_t substatus = static_cast<uint8_t>((dw0 >> 16) & 0xFFu);
const uint8_t status = static_cast<uint8_t>((dw0 >> 24) & 0xFFu);
if (status != 0 || substatus != 0) {
return {CompletionPollState::FAILED, PTO2_ERROR_ASYNC_COMPLETION_INVALID};
}
next_tail++;
}
if (next_tail != cur_tail) {
update_tail_info(cq_ctx, wq_ctx, next_tail);
const uint8_t substatus = static_cast<uint8_t>((dw0 >> 16) & 0xFFu);
const uint8_t status = static_cast<uint8_t>((dw0 >> 24) & 0xFFu);
if (status != 0 || substatus != 0) {
+next_tail;
update_tail_info(cq_ctx, wq_ctx, next_tail);
return {CompletionPollState::FAILED, PTO2_ERROR_ASYNC_COMPLETION_INVALID};
}
🤖 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/a5/runtime/tensormap_and_ringbuffer/runtime/backend/urma/urma_completion_scheduler.h`
around lines 192 - 201, Update the CQE processing loop so a failed completion is
consumed before returning failure: advance next_tail past the failed CQE and
call update_tail_info with the new tail before returning
CompletionPollState::FAILED. Preserve the existing failure status and
successful-CQE handling.

@jvjhfhg

jvjhfhg commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Requesting changes: the host-side URMA workspace needs the same opt-in macro gating as the SDMA overlay — the a5 CI environment is not ready for it (see #1315).

The reason for gating is environmental, not code quality: as documented in #1315, the current st-onboard-a5 CI CANN drops do not expose working async primitives (CANN 9.1.T500: aclrtSynchronizeStream AICPU exception 0x715002a poisons the context and turns every subsequent kernel launch into 507018; CANN 9.1.0 timestamp=20260625: HcclCommInitRootInfo returns HCCL_E_INTERNAL (4)). #1179's SDMA overlay was gated behind SIMPLER_ENABLE_PTO_SDMA_WORKSPACE (default OFF) for exactly this reason. This PR wires the PTO-ISA URMA workspace in unconditionally, going further than the SDMA overlay did:

  1. CMake: PTO_ISA_ROOT becomes a hard FATAL_ERROR requirement for every a5 host_runtime build (src/a5/platform/onboard/host/CMakeLists.txt). The SDMA overlay guards this behind option(SIMPLER_ENABLE_PTO_SDMA_WORKSPACE ... OFF).
  2. comm_hccl.cpp: the #include "pto/comm/async/urma/urma_workspace_manager.hpp", the urma_workspace members on CommHandle_ / DomainAllocation, and the init calls are all unconditional. Compare with the SDMA paths, which are #ifdef SIMPLER_ENABLE_PTO_SDMA_WORKSPACE / no-op when OFF.
  3. Failure blast radius: comm_alloc_windows now does if (!ensure_base_urma_workspace(h)) return -1; (+ file_barrier), and domain_alloc_via_ipc returns -1 when URMA init fails on dense mappings. On the current CI CANN, every a5 communication case would break — the exact failure mode [Code Health] Require upgraded a5 environment supporting sdma #1315 tracks for SDMA.
  4. No escape hatch: no env-var→CMake-define forwarding in runtime_compiler.py / runtime_builder.py, no _urma_workspace_enabled()-style check, no test skip gate. The PTO_URMA_SUPPORTED ifdefs in urma_completion_kernel.h are a pto-isa capability macro, not a simpler-side opt-in, and the host side doesn't consult it.
  5. Version guard gap: per [Code Health] Require upgraded a5 environment supporting sdma #1315 / [Code Health] Extend PTO-ISA build/run version guard to a5 onboard SDMA overlay (missed after #1179) #1351, compiling pto-isa headers into a5 host_runtime.so today happens with no pin verification, no build-metadata recording, no load-time staleness rejection, and no cmake-cache/ccache invalidation on a pin bump — the Validate PTO-ISA revision against runtime build #1096/fix(build): rebuild onboard a2a3 host_runtime on pto-isa commit change #1194 guard is still arch == "a2a3" only. This PR makes that exposure unconditional.

Asks:

@jvjhfhg jvjhfhg changed the title Add A5 URMA deferred completion backend feat(a5): add URMA deferred completion backend for tensormap_and_ringbuffer Jul 20, 2026
@jvjhfhg
jvjhfhg merged commit ca00026 into hw-native-sys:main Jul 20, 2026
16 checks passed
jvjhfhg pushed a commit that referenced this pull request Jul 22, 2026
Add a minimal two-rank smoke test under
examples/a5/tensormap_and_ringbuffer/urma_deferred_completion_demo,
mirroring the SDMA async completion demo but driving the URMA deferred
completion backend from #1392:

- Each rank stages its input inside the HCCL/URMA communication domain
  (256 B reserved head + input window).
- The producer issues a deferred UrmaTget from the peer rank's input
  window into local out, resolving the remote address through
  pto2::urma_backend::peer_mr_ptr on the URMA workspace.
- The consumer depends on out and computes result = out + 1; host-side
  validation checks both against the peer input, exercising URMA
  completion polling and deferred-release dependency handling.

Isolation per #1315: the demo is examples-only, self-skips unless
SIMPLER_ENABLE_PTO_URMA_WORKSPACE=ON (env-var gate at collection,
RuntimeError in run(), workSpace==0 self-skip in the kernel), and
stays out of CI until the URMA overlay is enabled for the a5
environment.
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