Add: support dynamic Graph boundary scalars on A5 - #1777
Conversation
Ports a2a3 host_build_graph PR hw-native-sys#1732 to A5. The A5 runtime was ported in hw-native-sys#1733 from an a2a3 snapshot predating hw-native-sys#1732; the parity follow-ups hw-native-sys#1736/hw-native-sys#1737 it promised were never opened, so A5 has been missing dynamic Graph boundary scalar support. Mirrors hw-native-sys#1732 line-for-line (the two trees are structurally identical on this surface): - Arg tracks scalar provenance (source pointer + invalidation flag) across add_scalars/add_scalars_i32/add_scalar_one/copy_scalars_from; a mutable scalar() access invalidates a forwarded boundary source so it is re-read at replay. - New wire/POD types GraphScalarSource, GraphScalarSourceRef, GraphScalarPatch; GraphDefinition gains boundary_scalar_count and off_scalar_sources; GraphSubmission replaces its reserved pad with scalars_offset + scalar_count. - graph_execution_storage_layout/_bytes gain a scalar_patch_capacity argument; all call sites updated together. - Recording classifies each scalar as static or boundary; the Definition stores boundary provenance, and first materialization plus affine replay refresh only the dynamic scalar slots. - rt_graph_args_cacheable and rt_submit_graph_impl drop the scalar_count()==0 rejection that previously forbade boundary scalars. Verified: full no-hardware C++ unit suite (92/92, including new test_a5_graph_cache boundary-scalar cases) and the A5 graph_execution a5sim scenes (3/3). 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (11)
📝 WalkthroughWalkthroughThe graph runtime now supports dynamic boundary scalar arguments. It tracks scalar provenance, serializes scalar source metadata, allocates scalar patch storage, refreshes boundary values during replay, and validates cacheability, storage, and scalar-count constraints. ChangesDynamic scalar replay
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant GraphRecorder
participant GraphDefinition
participant GraphExecution
participant BoundaryScalars
Caller->>GraphRecorder: submit graph with scalar arguments
GraphRecorder->>GraphDefinition: record scalar source references
GraphDefinition->>GraphExecution: materialize graph definition
GraphExecution->>BoundaryScalars: read runtime boundary scalar values
BoundaryScalars->>GraphExecution: provide scalar values
GraphExecution->>GraphExecution: apply scalar patches during replay
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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. Comment |
…RAPH task Ports a2a3 host_build_graph PR hw-native-sys#1731 to A5. Mirrors hw-native-sys#1731 line-for-line. With hw-native-sys#1777 in place, the scalar-source machinery hw-native-sys#1731's recording path depends on now exists on A5, so the port is direct: - PTO2TaskAllocator gains reserve_heap_scratch / restore_heap_top. - The recording pass routes submit_task / submit_dummy_task / alloc_tensors to graph_record_submit_node, which records each node's layout off the ring — output buffers come from heap scratch (released in graph_end) instead of a task-window slot. No ring slot, tensormap, fanin-pool entry, or upload is produced for an internal node. - A scope inside a Graph body is a no-op during recording. - graph_end rolls the heap back to the recording watermark, compacts and caches the Definition, and emits the single outer GRAPH task. It now returns bool; when the outer task cannot be placed, the body re-runs on the ordinary path so its work is still submitted. - The graph_end ops-table entry changes void -> bool in both mirrored ops structs. The first invocation now occupies one ring slot and one heap block instead of one per internal node. Verified: full no-hardware C++ unit suite (92/92) and the A5 graph_execution a5sim scenes (3/3).
…RAPH task (#1780) Ports a2a3 host_build_graph PR #1731 to A5. Mirrors #1731 line-for-line. With #1777 in place, the scalar-source machinery #1731's recording path depends on now exists on A5, so the port is direct: - PTO2TaskAllocator gains reserve_heap_scratch / restore_heap_top. - The recording pass routes submit_task / submit_dummy_task / alloc_tensors to graph_record_submit_node, which records each node's layout off the ring — output buffers come from heap scratch (released in graph_end) instead of a task-window slot. No ring slot, tensormap, fanin-pool entry, or upload is produced for an internal node. - A scope inside a Graph body is a no-op during recording. - graph_end rolls the heap back to the recording watermark, compacts and caches the Definition, and emits the single outer GRAPH task. It now returns bool; when the outer task cannot be placed, the body re-runs on the ordinary path so its work is still submitted. - The graph_end ops-table entry changes void -> bool in both mirrored ops structs. The first invocation now occupies one ring slot and one heap block instead of one per internal node. Verified: full no-hardware C++ unit suite (92/92) and the A5 graph_execution a5sim scenes (3/3).
Ports a2a3
host_build_graphPR #1732 (dynamic Graph boundary scalars) to A5.Why
A5 Graph Execution was ported in #1733 from an a2a3 snapshot taken before #1732 landed. #1733 deferred cross-arch parity to follow-ups #1736/#1737, which were never opened — so the A5 HBG runtime has been sitting at the pre-#1732 baseline, missing dynamic Graph boundary scalar support (boundary
CoreTaskArgswith scalars were rejected with"… not supported in step 1").This closes that gap. The a2a3 and A5 HBG trees are structurally identical on the touched surface (shared base
TaskArgsTplinsrc/common/task_interface/task_args.h), so this is a line-for-line port of already-reviewed a2a3 code.What (mirrors #1732)
pto_types.h—Argtracks scalar provenance (source pointer + invalidation flag) acrossadd_scalars/add_scalars_i32/add_scalar_one/copy_scalars_from; a mutablescalar(i)access invalidates a forwarded boundary source so it is re-read at replay.graph_execution.h— new wire/POD typesGraphScalarSource,GraphScalarSourceRef,GraphScalarPatch;GraphDefinitiongainsboundary_scalar_countandoff_scalar_sources;GraphSubmissionreplaces its reserved pad withscalars_offset+scalar_count;graph_execution_storage_layout/_bytesgain ascalar_patch_capacityargument.scheduler/graph_execution.cpp— recording classifies each scalar as static or boundary; the Definition stores boundary provenance, and first materialization plus affine replay refresh only the dynamic scalar slots (leaving static slots untouched).graph_cache.h/pto_orchestration_api.h— drop thescalar_count()==0rejection that previously forbade boundary scalars.runtime_maker.cpp, scheduler, unit test).This is PR 1 of 2; PR 2 ports #1731 (record Graph off the ring) on top of this branch.
Testing
test_a5_graph_cacheboundary-scalar cases:AcceptsBoundaryScalars,ConfigValuesSelectDifferentDefinitions,GraphScalarProvenance.*)Refs #1732.
🤖 Generated with Claude Code