Skip to content

Refactor: consolidate per-task markers into one TaskAttrs byte (a2a3 + a5 tmr) - #1410

Merged
ChaoZheng109 merged 1 commit into
hw-native-sys:mainfrom
ChaoZheng109:refactor/issue-1402-task-markers-byte
Jul 22, 2026
Merged

ChaoZheng109 merged 1 commit into
hw-native-sys:mainfrom
ChaoZheng109:refactor/issue-1402-task-markers-byte

Conversation

@ChaoZheng109

@ChaoZheng109 ChaoZheng109 commented Jul 20, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Consolidates the four scattered per-task markers in tensormap_and_ringbuffer into a single TaskAttrs byte on PTO2TaskSlotState, and reverts active_mask to a pure subtask-slot mask. Addresses code-health issue #1402. Covers both a2a3/tmr (baseline) and a5/tmr (1:1 port — a5/tmr was structurally identical).

Before, the four markers lived in three places with inconsistent rationale:

  • sync_start / has_predicate squatted in active_mask's spare high bits (bits 3-4)
  • the timing tag lived in the PTO2TaskDescriptor pad — a cold cache line, read via a pointer hop on the completion path
  • allow_early_resolve used a whole byte for one bool

Changes (per runtime, a2a3 + a5)

  • New TaskAttrs (pto_submit_types.h) — one byte: bit0 allow_early_resolve, bit1 sync_start, bit2 has_predicate, bit3 is_timed, bits4-7 timing_tag (0..15). is_timed distinguishes "untagged" from the 16 valid tag values.
  • ActiveMask reverts to a pure subtask-slot mask — dropped the SYNC_START/HAS_PREDICATE flag bits and accessors; it carries only core_mask (bits 0-2) and can be OR/==-combined for MIX clusters without dragging flag bits.
  • task_timing_slot removed from PTO2TaskDescriptor — the tag now rides the scheduler's hot slot_state line (better completion-path locality). Descriptor size (40B) and packed_buffer_base offset unchanged (shared-memory ABI preserved).
  • PTO2TaskSlotState stays exactly 64 bytes — task_attrs reuses the byte allow_early_resolve occupied, alongside the atomic lifecycle_flags.
  • Attributes written once per submit in prepare_task (alongside active_mask), assembled at each submit entry point. All scheduler read sites read the attributes off slot_state.
  • static_assert couples the 4-bit tag field to NUM_TASK_TIMING_SLOTS <= 16 / TASK_TIMING_SLOT_NONE == -1.

Accessor naming: getters are predicates (allow_early_resolve / requires_sync_start / has_predicate / is_timed); setters are set_<concept> (set_early_resolve / set_sync_start / set_predicate / set_timing_slot).

Performance is neutral (measured): pulling flags out of active_mask costs at most one extra L1-hit ldrb, dwarfed by the ~95 ns MMIO write_reg on the dispatch path; the timing tag improves completion-path locality. An a2a3 same-device A/B (both fresh worktrees, 100 rounds × 6 examples) showed deltas within the ±5% run-to-run noise floor with no consistent direction; the most stable workload (qwen3 decode) was flat (+0.3%).

Commits

  1. TaskAttrs byte — a2a3/tmr (baseline; includes UT + DFX/RUNTIME_LOGIC docs).
  2. TaskAttrs byte — a5/tmr (1:1 port; a5 has no marker UT, so runtime src + a5 RUNTIME_LOGIC.md only).

Testing

  • cpp UT: test_task_timing_slots + test_wiring (a2a3, 60/60 non-hardware), test_a5_wiring
  • a2a3sim st: predicated_dispatch, early_dispatch, spmd_sync_start{,_aiv,_early_dispatch,_edge,_mix_spill,_stress}, mixed_example, spmd_multiblock_mix, dummy_task, alternating_matmul_add, dfx
  • a5sim st: predicated_dispatch, spmd_sync_start{,_early_dispatch,_stress,_mix_spill}, mixed_example, dummy_task, spmd_multiblock_mix
  • a2a3 hardware A/B benchmark (neutral, within noise)
  • a5 hardware — deferred (this box is Ascend910/a2a3; a5 silicon unavailable here)

Relation to #1402

a2a3/tmr + a5/tmr done here. Remaining per the issue: a2a3 host_build_graph and a5 host_build_graph (legacy Runtime::Task path) — follow-up. Fixes #1402.

@coderabbitai

coderabbitai Bot commented Jul 20, 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

Run ID: e74ff5e2-91f5-4608-acd0-cbdd0ac91e5f

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 introduces a packed TaskMarkers byte for scheduling flags and timing tags, removes descriptor-based timing storage, and updates task submission, routing, early dispatch, completion, documentation, and tests to use the new representation.

Changes

Task marker consolidation

Layer / File(s) Summary
TaskMarkers contract and slot layout
src/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_submit_types.h, src/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_runtime2_types.h, src/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_types.h, tests/ut/cpp/a2a3/test_task_timing_slots.cpp, docs/dfx/device-phases.md
TaskMarkers stores scheduling flags and timing tags in one byte; ActiveMask retains only subtask-slot bits, and descriptor and timing ABI tests are updated.
Task marker submission plumbing
src/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_orchestrator.cpp
Task, dummy-task, allocation, and fan-in preparation paths construct, propagate, and update TaskMarkers.
Marker-based routing and early dispatch
src/a2a3/runtime/tensormap_and_ringbuffer/runtime/scheduler/pto_scheduler.h, src/a2a3/runtime/tensormap_and_ringbuffer/runtime/scheduler/scheduler_dispatch.cpp, src/a2a3/runtime/tensormap_and_ringbuffer/docs/RUNTIME_LOGIC.md, tests/ut/cpp/a2a3/test_wiring.cpp
Routing, predication, sync-start selection, early-dispatch gating, and wiring tests use task_markers accessors.
Timing completion and promotion
src/a2a3/runtime/tensormap_and_ringbuffer/runtime/scheduler/scheduler_completion.cpp
Completion timing and sync-start promotion read timing and routing state from TaskMarkers.

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

Possibly related PRs

Poem

A bunny packed flags in a byte,
Timing tags hopped into sight.
Old pads said goodbye,
New markers fly,
And sync lanes now route just right.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.69% 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
Linked Issues check ✅ Passed The changes implement the requested TaskMarkers layout, keep active_mask to core bits, preserve slot_state size, and remove task_timing_slot from the descriptor.
Out of Scope Changes check ✅ Passed All changes stay within the marker refactor, docs, and tests, with no unrelated scope added.
Title check ✅ Passed The title summarizes the main refactor to consolidate per-task markers into one byte and mentions the runtime scope.
Description check ✅ Passed The description is clearly about the same marker-consolidation refactor and related runtime 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 refactors per-task scheduling flags by consolidating them into a new 1-byte TaskMarkers struct on PTO2TaskSlotState. This change moves the selective timing tag off the PTO2TaskDescriptor (preserving its 40-byte shared-memory ABI size) and onto the scheduler's hot cache line. It also simplifies ActiveMask to be a pure subtask-slot mask (AIC/AIV0/AIV1) without carrying unrelated flag bits. Corresponding updates are made across the orchestrator, scheduler, documentation, and unit tests. I have no feedback to provide as there are no review comments.

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.

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

🧹 Nitpick comments (1)
src/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_runtime2_types.h (1)

207-209: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Add a compile-time offset guard alongside the size guard.

The comment states both descriptor size and packed_buffer_base offset are part of the ABI, but only sizeof is enforced with a static_assert here — the offset is only verified in the unit test (DescriptorDoesNotGrow). A header-level assert catches an accidental offset shift even without running tests.

♻️ Proposed addition
+// packed_buffer_base sits after the 4-byte alignment pad following kernel_id[3];
+// the shared-memory ABI depends on this offset staying fixed too.
+static_assert(
+    offsetof(PTO2TaskDescriptor, packed_buffer_base) == 24,
+    "PTO2TaskDescriptor::packed_buffer_base offset is part of the shared-memory ABI"
+);
 static_assert(sizeof(PTO2TaskDescriptor) == 40, "PTO2TaskDescriptor size is part of the shared-memory ABI");
🤖 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/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_runtime2_types.h`
around lines 207 - 209, Add a header-level static_assert alongside the existing
PTO2TaskDescriptor size assertion to verify that packed_buffer_base remains at
its ABI-defined offset. Use the established descriptor layout and offsetof-based
check, preserving the existing size guard and avoiding changes to the structure
layout.
🤖 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.

Nitpick comments:
In `@src/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_runtime2_types.h`:
- Around line 207-209: Add a header-level static_assert alongside the existing
PTO2TaskDescriptor size assertion to verify that packed_buffer_base remains at
its ABI-defined offset. Use the established descriptor layout and offsetof-based
check, preserving the existing size guard and avoiding changes to the structure
layout.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0eaa1daf-c7d0-4b68-8137-71d26eb8c867

📥 Commits

Reviewing files that changed from the base of the PR and between ee40a7f and f1bf03f.

📒 Files selected for processing (11)
  • docs/dfx/device-phases.md
  • src/a2a3/runtime/tensormap_and_ringbuffer/docs/RUNTIME_LOGIC.md
  • src/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_orchestrator.cpp
  • src/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_runtime2_types.h
  • src/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_submit_types.h
  • src/a2a3/runtime/tensormap_and_ringbuffer/runtime/pto_types.h
  • src/a2a3/runtime/tensormap_and_ringbuffer/runtime/scheduler/pto_scheduler.h
  • src/a2a3/runtime/tensormap_and_ringbuffer/runtime/scheduler/scheduler_completion.cpp
  • src/a2a3/runtime/tensormap_and_ringbuffer/runtime/scheduler/scheduler_dispatch.cpp
  • tests/ut/cpp/a2a3/test_task_timing_slots.cpp
  • tests/ut/cpp/a2a3/test_wiring.cpp

@ChaoZheng109
ChaoZheng109 force-pushed the refactor/issue-1402-task-markers-byte branch 2 times, most recently from fbaf109 to eea58ae Compare July 22, 2026 02:45
@ChaoZheng109 ChaoZheng109 changed the title Refactor: consolidate per-task markers into one TaskMarkers byte (a2a3/tmr) Refactor: consolidate per-task markers into one TaskAttrs byte (a2a3/tmr) Jul 22, 2026
@ChaoZheng109
ChaoZheng109 force-pushed the refactor/issue-1402-task-markers-byte branch from eea58ae to 4c92922 Compare July 22, 2026 03:04
@ChaoZheng109 ChaoZheng109 changed the title Refactor: consolidate per-task markers into one TaskAttrs byte (a2a3/tmr) Refactor: consolidate per-task markers into one TaskAttrs byte (a2a3 + a5 tmr) Jul 22, 2026
@ChaoZheng109
ChaoZheng109 force-pushed the refactor/issue-1402-task-markers-byte branch from 0d47644 to 0aa3142 Compare July 22, 2026 06:03
…+ a5 tmr)

Four independent per-task markers were scattered across three storage
sites: sync_start / has_predicate squatted in active_mask's spare high
bits, the timing tag lived in the PTO2TaskDescriptor pad (a cold cache
line), and allow_early_resolve used a whole byte for one bool.

Consolidate all four into a single TaskAttrs byte on PTO2TaskSlotState,
reusing the byte allow_early_resolve already occupied (slot_state stays
64 bytes), and revert active_mask to a pure subtask-slot mask. Applied to
both tensormap_and_ringbuffer runtimes (a2a3 baseline + a5 1:1 port, which
was structurally identical).

- Add TaskAttrs (pto_submit_types.h): bit0 allow_early_resolve,
  bit1 sync_start, bit2 has_predicate, bit3 is_timed, bits4-7 timing_tag.
  is_timed distinguishes "untagged" from the 16 valid tag values.
- Drop SYNC_START/HAS_PREDICATE flag bits and their accessors from
  ActiveMask; it now carries only core_mask (bits 0-2) and can be
  OR/==-combined for MIX clusters without dragging flag bits.
- Remove task_timing_slot from PTO2TaskDescriptor; the tag now rides the
  scheduler's hot slot_state line. Descriptor size/ABI (40B,
  packed_buffer_base offset) unchanged; task_attrs coexists with the
  atomic lifecycle_flags byte.
- prepare_task writes task_attrs per submit alongside active_mask;
  attributes are assembled at each submit entry point (submit_task,
  submit_dummy_task, alloc_tensors).
- Update all scheduler read sites (dispatch/completion/scheduler.h) to
  read the attributes off slot_state.
- Static-assert NUM_TASK_TIMING_SLOTS <= 16 and TASK_TIMING_SLOT_NONE
  == -1 so the 4-bit tag field and the untagged sentinel stay coupled.

Accessor naming: getters are predicates (allow_early_resolve /
requires_sync_start / has_predicate / is_timed); setters are set_<concept>
(set_early_resolve / set_sync_start / set_predicate / set_timing_slot).

Behavior-neutral refactor; a2a3 same-device A/B benchmark is within the
run-to-run noise floor. Updated test_task_timing_slots (TaskAttrs roundtrip
replaces the descriptor-field test), test_wiring, and the DFX/RUNTIME_LOGIC
docs. Mirroring to a2a3 host_build_graph and a5 host_build_graph is left as
follow-up. Fixes hw-native-sys#1402.
@ChaoZheng109
ChaoZheng109 merged commit 1de0474 into hw-native-sys:main Jul 22, 2026
29 of 31 checks passed
jvjhfhg added a commit that referenced this pull request Jul 22, 2026
The TaskAttrs migration (#1410) moved has_predicate off ActiveMask but
missed this SIMPLER_DFX-only call site in the a5 tmr scheduler (the
a2a3 twin was missed too). DFX-enabled builds fail with 'ActiveMask
has no member named has_predicate'.
ChaoWao added a commit that referenced this pull request Jul 22, 2026
…p path (#1445)

#1410 consolidated the per-task dispatch predicates into the TaskAttrs byte,
moving has_predicate() from ActiveMask to TaskAttrs and updating the scheduler
call sites. It missed the two dummy-drain swimlane-skip calls that #1419 added:
a2a3 and a5 tensormap_and_ringbuffer scheduler_dispatch.cpp still call
dummy_slot.active_mask.has_predicate(). ActiveMask no longer has that member, so
the default build (the calls sit under SIMPLER_DFX, which is on by default) fails
to compile a2a3sim / a5sim. The two PRs were each green against their own base;
the break only appears once both are on main.

Point both call sites at dummy_slot.task_attrs.has_predicate(), matching every
other has_predicate() caller in the scheduler. a2a3sim and a5sim build clean.
jvjhfhg added a commit that referenced this pull request Jul 23, 2026
The TaskAttrs migration (#1410) moved has_predicate off ActiveMask but
missed this SIMPLER_DFX-only call site in the a5 tmr scheduler (the
a2a3 twin was missed too). DFX-enabled builds fail with 'ActiveMask
has no member named has_predicate'.
YunjiQin added a commit to YunjiQin/simpler that referenced this pull request Jul 27, 2026
PR hw-native-sys#1410 moved has_predicate() off ActiveMask onto TaskAttrs for the tensormap_and_ringbuffer runtime,
but hw-native-sys#1419's predicated-skip swimlane call site in scheduler_dispatch.cpp (a2a3 + a5) still read
active_mask.has_predicate(), which fails to compile under SIMPLER_DFX ('class ActiveMask' has no member
has_predicate). Point it at dummy_slot.task_attrs.has_predicate(), matching every other TMR call site.
host_build_graph is unaffected (hw-native-sys#1410 was TMR-only). Build-required on this branch (the broken call site
is inherited from main).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

[Code Health] Consolidate scattered per-task markers into one "task markers" byte; keep active_mask a pure subtask-slot mask

1 participant