Skip to content

Add: port a2a3 eager prewarm arena to a5 tmr#1451

Open
yanghaoran29 wants to merge 1 commit into
hw-native-sys:mainfrom
yanghaoran29:a5-prewarm-arena-port
Open

Add: port a2a3 eager prewarm arena to a5 tmr#1451
yanghaoran29 wants to merge 1 commit into
hw-native-sys:mainfrom
yanghaoran29:a5-prewarm-arena-port

Conversation

@yanghaoran29

Copy link
Copy Markdown
Contributor

Onboard effect (a5, ring_task_window=64, dummy_task): cold first-run bind.prebuilt ~9.58 ms -> hot ~0.002 ms; ~9.97 ms build cost shifts to init simpler_prewarm.build (cache hit on first run).

- Align a5 runtime_maker with a2a3 hw-native-sys#1322: shared
  build_and_cache_prebuilt_arena, strong prewarm_config_impl,
  decouple ensure_static_arenas from Runtime
- Add a5 prewarm regression test and onboard cold/hot benchmark

Onboard effect (a5, ring_task_window=64, dummy_task):
cold first-run bind.prebuilt ~9.58 ms -> hot ~0.002 ms; ~9.97 ms
build cost shifts to init simpler_prewarm.build (cache hit on first run).
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The runtime arena miss path now uses a shared build/upload/cache helper, while cache hits and newly built arenas are wired directly. A new prewarm_config_impl entrypoint supports eager cache population, with benchmark and L2 initialization coverage.

Changes

Runtime arena prewarming

Layer / File(s) Summary
Arena build and cache pipeline
src/a5/runtime/tensormap_and_ringbuffer/host/runtime_maker.cpp
Static arena setup is separated from runtime wiring, and build_and_cache_prebuilt_arena centralizes sizing, reservation, image construction, upload, and cache storage.
Binding and prewarm integration
src/a5/runtime/tensormap_and_ringbuffer/host/runtime_maker.cpp
Cache-hit wiring remains metadata-based, cache misses wire newly built arenas directly, and prewarm_config_impl eagerly populates the cache from ring sizing values.
Prewarm measurement and regression coverage
tests/st/a5/tensormap_and_ringbuffer/bench_prewarm_timing.py, tests/st/a5/tensormap_and_ringbuffer/test_prewarm_config.py
The benchmark compares cold and hot timings, while the regression test validates L2 initialization with prewarm_config.

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

Sequence Diagram(s)

sequenceDiagram
  participant Worker
  participant prewarm_config_impl
  participant build_and_cache_prebuilt_arena
  participant RuntimeArenaCache
  Worker->>prewarm_config_impl: provide ring sizing configuration
  prewarm_config_impl->>build_and_cache_prebuilt_arena: build and upload arena image
  build_and_cache_prebuilt_arena->>RuntimeArenaCache: store prebuilt runtime image
  Worker->>RuntimeArenaCache: bind configured runtime
  RuntimeArenaCache-->>Worker: return cached arena metadata
Loading

Possibly related PRs

Poem

A rabbit watched the arenas bloom,
Built and cached to clear the room.
Cold runs hop, then hot runs race,
Prewarm puts speed in its place.
“Bind,” says the bun, “with less delay!” 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly reflects the main change: porting eager prewarm arena support from a2a3 to a5 tmr.
Description check ✅ Passed The description matches the implemented runtime changes, regression test, and benchmark additions.
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

🧹 Nitpick comments (1)
tests/st/a5/tensormap_and_ringbuffer/test_prewarm_config.py (1)

19-36: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Solid smoke test, but doesn't exercise the cache-hit path it's meant to protect.

This confirms worker.init(prewarm_config=...) doesn't crash, but never follows up with register/run using matching ring sizing to confirm the prewarmed image is actually consumed on bind (i.e., that the cache-hit branch in bind_callable_to_runtime_impl is reached rather than a silent fallback to the miss path).

     worker = Worker(
         level=2,
         device_id=int(st_device_ids[0]),
         platform=st_platform,
         runtime=_RUNTIME,
     )
     try:
         worker.init(prewarm_config=config)
+        # Exercise a bind with matching ring sizing and assert it takes the
+        # cache-hit path (e.g. via a callable register/run + STRACE assertion).
     finally:
         worker.close()
🤖 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 `@tests/st/a5/tensormap_and_ringbuffer/test_prewarm_config.py` around lines 19
- 36, Extend test_l2_init_with_prewarm_config to register and run a workload
after worker.init using the same ring_task_window=64 configuration, ensuring the
prewarmed image is consumed during binding. Exercise the
bind_callable_to_runtime_impl cache-hit path and retain the existing worker
cleanup.
🤖 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 `@tests/st/a5/tensormap_and_ringbuffer/bench_prewarm_timing.py`:
- Around line 165-184: Make all timing output in the displayed per-run and
“both” summary paths None-safe. Reuse the existing formatting approach from
prewarm_text for parsed bind_prebuilt_strace_ms, cold, hot, and prewarm_ms
values, ensuring missing timings print a fallback such as “None” instead of
applying :.2f; preserve the existing guarded savings calculations.

---

Nitpick comments:
In `@tests/st/a5/tensormap_and_ringbuffer/test_prewarm_config.py`:
- Around line 19-36: Extend test_l2_init_with_prewarm_config to register and run
a workload after worker.init using the same ring_task_window=64 configuration,
ensuring the prewarmed image is consumed during binding. Exercise the
bind_callable_to_runtime_impl cache-hit path and retain the existing worker
cleanup.
🪄 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 Plus

Run ID: 07025a8b-2d83-4aa5-8494-16509183e5af

📥 Commits

Reviewing files that changed from the base of the PR and between c032e07 and 01a3c43.

📒 Files selected for processing (3)
  • src/a5/runtime/tensormap_and_ringbuffer/host/runtime_maker.cpp
  • tests/st/a5/tensormap_and_ringbuffer/bench_prewarm_timing.py
  • tests/st/a5/tensormap_and_ringbuffer/test_prewarm_config.py

Comment on lines +165 to +184
prewarm_val = parsed["simpler_prewarm_build_ms"]
prewarm_text = f"{prewarm_val:.2f}ms" if prewarm_val is not None else "None"
print(
f" -> bind.prebuilt(STRACE)={parsed['bind_prebuilt_strace_ms']:.2f}ms"
f", prewarm.build={prewarm_text}",
flush=True,
)

if args.mode == "both":
cold = results["cold"]["bind_prebuilt_strace_ms"]
hot = results["hot"]["bind_prebuilt_strace_ms"]
prewarm_ms = results["hot"]["simpler_prewarm_build_ms"]
print("\n=== SUMMARY ===")
print(f"cold first-run bind.prebuilt (STRACE) : {cold:.2f} ms")
print(f"hot first-run bind.prebuilt (STRACE) : {hot:.2f} ms")
print(f"hot init simpler_prewarm.build : {prewarm_ms:.2f} ms")
if cold is not None and hot is not None:
print(f"first-run savings (cold - hot) : {cold - hot:.2f} ms")
if prewarm_ms is not None:
print(f"(build cost shifted to init prewarm) : ~{prewarm_ms:.2f} ms")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Unguarded .2f formatting on possibly-None timing values.

_parse_log types bind_prebuilt_strace_ms/simpler_prewarm_build_ms as float | None, and line 166 already guards against None for prewarm_text, but lines 168, 178, 179, and 180 format these values directly with :.2f with no None check. If a TIMING/STRACE log line fails to match (e.g. log-level or format drift), this raises TypeError and the benchmark crashes without reporting partial results, unlike the guarded delta computation at 181-184.

🐛 Proposed fix for None-safe formatting
+    def _fmt(v: float | None) -> str:
+        return f"{v:.2f}ms" if v is not None else "None"
+
         prewarm_val = parsed["simpler_prewarm_build_ms"]
         prewarm_text = f"{prewarm_val:.2f}ms" if prewarm_val is not None else "None"
         print(
-            f"  -> bind.prebuilt(STRACE)={parsed['bind_prebuilt_strace_ms']:.2f}ms"
+            f"  -> bind.prebuilt(STRACE)={_fmt(parsed['bind_prebuilt_strace_ms'])}"
             f", prewarm.build={prewarm_text}",
             flush=True,
         )
 
     if args.mode == "both":
         cold = results["cold"]["bind_prebuilt_strace_ms"]
         hot = results["hot"]["bind_prebuilt_strace_ms"]
         prewarm_ms = results["hot"]["simpler_prewarm_build_ms"]
         print("\n=== SUMMARY ===")
-        print(f"cold first-run bind.prebuilt (STRACE) : {cold:.2f} ms")
-        print(f"hot  first-run bind.prebuilt (STRACE) : {hot:.2f} ms")
-        print(f"hot  init simpler_prewarm.build        : {prewarm_ms:.2f} ms")
+        print(f"cold first-run bind.prebuilt (STRACE) : {_fmt(cold)}")
+        print(f"hot  first-run bind.prebuilt (STRACE) : {_fmt(hot)}")
+        print(f"hot  init simpler_prewarm.build        : {_fmt(prewarm_ms)}")
📝 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
prewarm_val = parsed["simpler_prewarm_build_ms"]
prewarm_text = f"{prewarm_val:.2f}ms" if prewarm_val is not None else "None"
print(
f" -> bind.prebuilt(STRACE)={parsed['bind_prebuilt_strace_ms']:.2f}ms"
f", prewarm.build={prewarm_text}",
flush=True,
)
if args.mode == "both":
cold = results["cold"]["bind_prebuilt_strace_ms"]
hot = results["hot"]["bind_prebuilt_strace_ms"]
prewarm_ms = results["hot"]["simpler_prewarm_build_ms"]
print("\n=== SUMMARY ===")
print(f"cold first-run bind.prebuilt (STRACE) : {cold:.2f} ms")
print(f"hot first-run bind.prebuilt (STRACE) : {hot:.2f} ms")
print(f"hot init simpler_prewarm.build : {prewarm_ms:.2f} ms")
if cold is not None and hot is not None:
print(f"first-run savings (cold - hot) : {cold - hot:.2f} ms")
if prewarm_ms is not None:
print(f"(build cost shifted to init prewarm) : ~{prewarm_ms:.2f} ms")
def _fmt(v: float | None) -> str:
return f"{v:.2f}ms" if v is not None else "None"
prewarm_val = parsed["simpler_prewarm_build_ms"]
prewarm_text = f"{prewarm_val:.2f}ms" if prewarm_val is not None else "None"
print(
f" -> bind.prebuilt(STRACE)={_fmt(parsed['bind_prebuilt_strace_ms'])}"
f", prewarm.build={prewarm_text}",
flush=True,
)
if args.mode == "both":
cold = results["cold"]["bind_prebuilt_strace_ms"]
hot = results["hot"]["bind_prebuilt_strace_ms"]
prewarm_ms = results["hot"]["simpler_prewarm_build_ms"]
print("\n=== SUMMARY ===")
print(f"cold first-run bind.prebuilt (STRACE) : {_fmt(cold)}")
print(f"hot first-run bind.prebuilt (STRACE) : {_fmt(hot)}")
print(f"hot init simpler_prewarm.build : {_fmt(prewarm_ms)}")
if cold is not None and hot is not None:
print(f"first-run savings (cold - hot) : {cold - hot:.2f} ms")
if prewarm_ms is not None:
print(f"(build cost shifted to init prewarm) : ~{prewarm_ms:.2f} ms")
🤖 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 `@tests/st/a5/tensormap_and_ringbuffer/bench_prewarm_timing.py` around lines
165 - 184, Make all timing output in the displayed per-run and “both” summary
paths None-safe. Reuse the existing formatting approach from prewarm_text for
parsed bind_prebuilt_strace_ms, cold, hot, and prewarm_ms values, ensuring
missing timings print a fallback such as “None” instead of applying :.2f;
preserve the existing guarded savings calculations.

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.

1 participant