Skip to content

fix(metrics): sync the timeslice index and warmup baseline fixes with upstream aiperf - #59

Draft
weireweire wants to merge 3 commits into
SemiAnalysisAI:masterfrom
weireweire:fix/agentx-upstream-sync
Draft

weireweire wants to merge 3 commits into
SemiAnalysisAI:masterfrom
weireweire:fix/agentx-upstream-sync

Conversation

@weireweire

@weireweire weireweire commented Oct 20, 2026 •

Copy link
Copy Markdown

Summary

Keep the AgentX copies of #58 and #49 identical to their upstream form in ai-dynamo/aiperf, so later upstream syncs apply cleanly. This PR tracks ai-dynamo#1592 and will be updated whenever that PR changes.

Changes

1. Timeslice ragged index: skip records ingested after the export snapshot (follow-up to #58)

Same commit as the review fix on ai-dynamo#1592.

  • export_results runs in a worker thread while ingestion can continue. _build_slice_ragged_index indexed record_bin (sized at the snapshot) with every current record index, so a ragged value appended for a later record raised IndexError and aborted the export.
  • Record indices beyond the snapshot now map to no slice, as get_values_for_mask already does. Value positions are unchanged, so exported timeslices are unchanged.
  • Drops the redundant _compute_timeslice_bins docstring.

2. Timeslice ragged index: no shared per-computation state (follow-up to #58)

Same commit as the second review fix on ai-dynamo#1592.

  • perf(metrics): gather timeslice ragged values from a per-slice index #58 stored the slice index and the active slice on the accumulator while the export's slice loop ran. export_results runs in a worker thread and the realtime summarize runs on the event loop with no lock, so a summary that overlapped the slice loop gathered inter_chunk_latency from the export's current slice instead of its own mask.
  • The index is now a local of _compute_timeslices, and each slice's value positions are passed to _compute_results as an argument. The _compute_timeslice_bins split from perf(metrics): gather timeslice ragged values from a per-slice index #58 is undone; the slice loop is back to its original form plus that argument.
  • Index trim: int32 slice ids and positions, and slice bounds from bincount + cumsum. At 20 M values: 422 MB peak and 80 MB retained, down from 504 MB and 160 MB.
  • The only difference from upstream is in the new overlap test, which calls _summarize_for_export_context(..., include_timeslices=False) as AgentX's realtime summarize does (perf: skip unused live metric computations #53); upstream has no include_timeslices argument.

3. Warmup baseline tagging: align #49 with upstream

Upstream fixes the same bug with phase_kind="warmup" on the synthesized agentic warmup alone (ai-dynamo#1325). #49 also added a PhaseBaselineRequestMessage.phase fallback for boundaries without a kind. That fallback cannot trigger here: validated PhaseConfigs always carry a kind, and the agentic warmup now sets one.

  • Keeps phase_kind="warmup" and its test assertion.
  • Removes the phase message field, the publisher wiring, the manager fallback, their tests, and the added comments. The scrape tagging is now identical to upstream: phase_kind == "warmup" -> warmup, otherwise profiling.

Tests

  • New test_summary_overlapping_timeslice_export_keeps_its_own_values: a phase-scoped summary run in the middle of the export's slice loop matches its standalone result, and so does the export. On the commit before this fix the summary's inter_chunk_latency has 54 values (one warmup slice) instead of 6,849.
  • New test_ragged_values_ingested_after_snapshot_are_excluded: appends ragged values for a record past the snapshot while the index is built; timeslices match the export without them. It raises IndexError without the fix.
  • tests/unit/{post_processors,metrics,exporters,server_metrics,timing,records}: 3817 passed, 10 failed. The same 10 tests fail on master (test_completed_excludes_analyzer_metrics, test_auto_offset_affects_execution_duration x6, test_global_idle_cap_rechecks_after_barrier_defers_near_timer, test_offset_child_uses_shared_scheduler_for_idle_cap, test_produces_intermediate_values).
  • ruff check passes on the changed files.

…ice snapshot

Root cause: export_results runs in a worker thread while ingestion can
continue. _build_slice_ragged_index indexed record_bin, sized at the
snapshot, with every current record index, so a ragged value appended for a
later record raised IndexError and aborted the export.

Fix: map record indices beyond the snapshot to no slice, as
get_values_for_mask does, keeping value positions unchanged. Drop the
redundant _compute_timeslice_bins docstring.

Validation: new test appends ragged values for a record past the snapshot
while the index is built; the timeslices match the export without them.

Signed-off-by: weireweire <20922698+weireweire@users.noreply.github.com>
…ream

Root cause: ai-dynamo#49 fixed the agentic warmup-start scrape in two places: it set
phase_kind="warmup" on the synthesized agentic warmup, and it added a
PhaseBaselineRequestMessage.phase fallback for boundaries without a kind.
Upstream aiperf (ai-dynamo#1325) fixes it with phase_kind="warmup"
alone. The fallback cannot trigger: validated PhaseConfigs always carry a
kind, and the agentic warmup now sets one.

Fix: keep phase_kind="warmup" and its test assertion; drop the phase
fallback, the message field, the publisher wiring, their tests, and the
added comments, so this code matches upstream.

Validation: tests/unit/server_metrics and tests/unit/timing.
Signed-off-by: weireweire <20922698+weireweire@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Try out this PR

Quick install:

pip install --upgrade --force-reinstall git+https://github.com/ai-dynamo/aiperf.git@a75c9f3c83e8795a4d1bbbf0cf2ee05c4abbf182

Recommended with virtual environment (using uv):

uv venv --python 3.12 && source .venv/bin/activate
uv pip install --upgrade --force-reinstall git+https://github.com/ai-dynamo/aiperf.git@a75c9f3c83e8795a4d1bbbf0cf2ee05c4abbf182

Last updated for commit: a75c9f3 • Browse code

@github-actions github-actions Bot added the fix label Oct 20, 2026
…d of shared state

Root cause: the slice index and the active slice were stored on the
accumulator while the export's slice loop ran. export_results runs in a
worker thread, and the realtime summarize runs on the event loop with no
lock, so a summary that overlapped the slice loop gathered ragged values
from the export's current slice instead of its own mask.

Fix: build the index as a local in _compute_timeslices and pass each
slice's value positions to _compute_results as an argument; the
accumulator holds no per-computation state. Also trim the index: int32
slice ids and value positions, and slice bounds from bincount + cumsum
instead of a sorted copy and two searchsorted passes.

Validation: new test runs a phase-scoped summary in the middle of the
slice loop; both the export and the summary match their standalone
results. Existing index tests still match the per-slice mask path.

Signed-off-by: weireweire <20922698+weireweire@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant