feat(memory): trace exporters — Perfetto/Chrome JSON, JFR events, android.os.Trace (SKEEP-003 P2, S1.5b) - #1073
Merged
Conversation
…roid.os.Trace (SKEEP-003 P2) Milestone M1 (#1002), PRD M1-F7 / M1-A7, decision #12. The event stream from #1061 now has three consumers, so a decode loop can be *looked at*. - PerfettoTraceExporter (commonMain): renders TraceEvents as the Chrome trace JSON that Perfetto and chrome://tracing read — one track per scope (allocations on a thread named after their ScopeKind, phases and kernels on the main thread), phases as B/E slices, kernel runs as complete slices labelled by op, kernel name and TensorIds, adapter insertions as instants carrying their byte cost (the #782 class becomes a visible mark), live bytes per scope as counter tracks — which is what makes a flat decode loop look flat — and the memory plan as metadata. Timestamps convert ns -> µs without a platform formatter. - JfrTraceSink (jvmMain): the same events as JFR events under the SKaiNET category, so they open in the IntelliJ profiler or JMC next to JIT, GC and allocation data. Recording stays JFR's business (-XX:StartFlightRecording / jcmd JFR.start); isEnabled mirrors whether JFR has the event types enabled, so emission is a boolean check when it is not recording. - AndroidTraceSink (androidMain): forwards to android.os.Trace so a SKaiNET trace lines up with the OS view in Perfetto/systrace on device: phases and kernels as async sections, adapters/scope resets/allocations as counters, names truncated to the 127-character limit, everything guarded by Trace.isEnabled(). - PerfettoTraceExporterTest: a realistic decode step renders with the right tracks, slices, durations, TensorId labels, adapter bytes and a live-bytes counter that drops to zero at the scope reset; string escaping and ns->µs formatting are pinned. 11/11. Closes #1025 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
Local gate Targeted: |
|
📖 Documentation Preview The documentation has been built successfully for this PR. Generated Files:
Artifacts:
This comment will be updated automatically when the PR is updated. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SKEEP-003 slice S1.5b (milestone M1 #1002, PRD M1-F7 / M1-A7, decision #12): the event stream from #1061 gets its three consumers, so a decode loop can actually be looked at.
PerfettoTraceExporter(commonMain) — rendersTraceEvents as the Chrome trace JSON that Perfetto andchrome://tracingread, with the mapping §4.9 asks for: one track per scope (allocations on a thread named after theirScopeKind, phases and kernels on the main thread), phases asB/Eslices, kernel runs as complete slices labelled by op, kernel name andTensorIds, adapter insertions as instants carrying their byte cost (a silent dequantisation — the GGUF DEQUANTIZE_TO_FP32 over-allocates: 1.1B Q4_K_M needs >12 GB heap transiently (~4.4 GB legit) #782 class — becomes a mark on the timeline), live bytes per scope as counter tracks, and the memory plan as metadata. Timestamps convert ns → µs without a platform formatter.JfrTraceSink(jvmMain) — the same events as JFR events under aSKaiNETcategory, so a memory trace opens in the IntelliJ profiler or JMC next to JIT, GC and allocation data. Recording stays JFR's business (-XX:StartFlightRecording,jcmd JFR.start);isEnabledmirrors whether JFR has the event types enabled, so emission is one boolean check when nothing is recording.AndroidTraceSink(androidMain) — forwards toandroid.os.Traceso an on-device trace lines up with the OS view in Perfetto/systrace: phases and kernels as async sections, adapters / scope resets / allocations as counters, names truncated to the platform's 127-character limit, everything guarded byTrace.isEnabled().Evidence (
PerfettoTraceExporterTest, 11/11): a realistic decode step (plan → model allocation → decode phase → forward allocation → kernel run → adapter → scope reset → counter) renders with the right process/thread tracks, slice durations in µs,TensorIdlabels on the kernel span, the adapter's byte cost, and a live-bytes counter that drops back to zero at the scope reset — the visual signature M1-A7 describes. String escaping and ns→µs formatting are pinned.Test plan
Full local gate (
scripts/pr-gate.sh, JDK 25) — all legs passed; results in the first comment.Closes #1025
🤖 Generated with Claude Code