Skip to content

refactor(records): remove legacy results processors; route by record type#1144

Open
ajcasagrande wants to merge 1 commit into
mainfrom
ajc/accumulator-refactor-main
Open

refactor(records): remove legacy results processors; route by record type#1144
ajcasagrande wants to merge 1 commit into
mainfrom
ajc/accumulator-refactor-main

Conversation

@ajcasagrande

@ajcasagrande ajcasagrande commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Removes the legacy results_processor plugin category entirely and routes records dynamically by record_type through accumulators and stream exporters. Net +1,634 / −3,857 across 68 files.

Taxonomy

  • Delete the results_processor category and its registrations. Behavior moves to accumulator / stream_exporter / analyzer / data_exporter.
  • Delete legacy metric_results_processor, timeslice_metric_results_processor, record_export_results_processor, and the bespoke network_latency/protocols.
  • Rename otel_metrics_results_processorotel_metrics_streamer, and accuracy_results_processor → the accuracy accumulator.

RecordsManager

  • Replace the per-type processor lists and fan-out methods with a routing table built from plugin metadata and a single _dispatch_record(record) keyed on record.record_type. DERIVED metrics now resolve in MetricsAccumulator.

Accuracy

  • Move per-record grade transport off the accuracy. summary namespace to underscore keys (accuracy_correct / accuracy_unparsed) so the registered transport metrics no longer collide with the accuracy. summary tags — a collision that had been dropping the overall unparsed count.

Network-adjusted metrics

  • Wire network_adjusted_* latency metrics into per-timeslice results (previously only in the overall summary). The per-record adjustment max(latency − rtt, 0) is window-independent, so it is computed once over each full source column and both the overall summary and every timeslice aggregate masked views — no redundant per-window subtraction, and no double-application (the analyzer only reads the column store, never writes back).

Verification

  • Full unit suite: 14422 passed, 94 skipped, 1 xfailed.
  • Plugin artifacts + schemas validate; every registered plugin class imports (no dangling registrations).
  • record_type routing coverage complete: metric_records, gpu_telemetry, server_metrics, network_latency, credit_phase_stats all have consumers.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Introduced metadata-driven routing for accumulators and stream exporters.
    • Added explicit record types for metrics, telemetry, latency, server metrics, and credit data.
    • Improved network-adjusted latency calculations across overall and timeslice summaries.
    • Added accuracy aggregation support with clearer metric transport keys.
    • Enhanced JSONL and telemetry exporters with record processing and finalization.
  • Bug Fixes

    • Hidden internal and experimental metrics are now filtered appropriately in exports.
    • Improved unit conversion handling and error reporting.
    • Updated timeslice result representation and removed legacy processing paths.
  • Documentation

    • Updated plugin categories, CLI defaults, accuracy aggregation, metrics flow, and developer guidance.

…type

Remove the legacy `results_processor` plugin category entirely and route records
dynamically by `record_type` through accumulators and stream exporters.

Taxonomy
- Delete the `results_processor` category and its registrations. Behavior moves
  to `accumulator` / `stream_exporter` / `analyzer` / `data_exporter`.
- Delete legacy `metric_results_processor`, `timeslice_metric_results_processor`,
  `record_export_results_processor`, and the bespoke `network_latency/protocols`.
- Rename `otel_metrics_results_processor` -> `otel_metrics_streamer` and
  `accuracy_results_processor` -> the accuracy accumulator.

RecordsManager
- Replace the per-type processor lists and fan-out methods with a routing table
  built from plugin metadata and a single `_dispatch_record(record)` keyed on
  `record.record_type`. DERIVED metrics now resolve in MetricsAccumulator.

Accuracy
- Move per-record grade transport off the `accuracy.` summary namespace to
  underscore keys (`accuracy_correct` / `accuracy_unparsed`) so the registered
  transport metrics no longer collide with the `accuracy.` summary tags (which
  had been dropping the overall unparsed count).

Network-adjusted metrics
- Wire `network_adjusted_*` latency metrics into per-timeslice results (they were
  only in the overall summary). The per-record adjustment `max(latency - rtt, 0)`
  is window-independent, so it is computed once over each full source column and
  both the overall summary and every timeslice aggregate masked views -- no
  redundant per-window subtraction, and no double-application (the analyzer only
  reads the column store, never writes back).

Full unit suite: 14422 passed, 94 skipped, 1 xfailed. Plugin artifacts + schemas
validate; every registered plugin class imports.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Anthony Casagrande <acasagrande@nvidia.com>
@github-actions

Copy link
Copy Markdown

Try out this PR

Quick install:

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

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@17dabb5c97da8eba6afb113e2d4a02b06e552c00

Last updated for commit: 17dabb5Browse code

@github-actions

Copy link
Copy Markdown

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR replaces the legacy per-category "results processor" architecture with an accumulator/stream-exporter model. Records now carry a record_type discriminator and are dispatched via RecordsManager's metadata-driven routing table to registered accumulators and stream exporters, replacing MetricResultsProcessor, TimesliceMetricResultsProcessor, RecordExportResultsProcessor, and processor-specific protocols.

Estimated code review effort: 5 (Critical) | ~120 minutes

Changes

Accumulator/Router Migration

Layer / File(s) Summary
Plugin category schema and docs
src/aiperf/plugin/categories.yaml, enums.py, plugins.py, plugins.yaml, schema/plugins.schema.json, docs/plugins/plugin-system.md, docs/cli-options.md
Removes results_processor/gpu_telemetry_processor/server_metrics_processor categories, adds accumulator/stream_exporter categories, and updates CLI/docs defaults and category lists.
Accumulator/exporter protocols
src/aiperf/gpu_telemetry/protocols.py, server_metrics/protocols.py, network_latency/protocols.py, post_processors/protocols.py, strategies/core.py
Renames processor methods to process_record, removes legacy processor protocols, and adjusts export_results signatures.
Record type discriminators
common/messages/inference_messages.py, common/models/credit_models.py, network_latency_models.py, server_metrics_models.py, telemetry_models.py
Adds record_type ClassVar constants used for routing.
MetricsAccumulator core & network-adjusted logic
metrics/accumulator.py, network_adjusted_analyzer.py, display_units.py, base_aggregate_metric.py, derived_sum_metric.py, metric type docstrings, tests/unit/post_processors/*
Implements precompute-and-inject network RTT adjustment, hidden-metric filtering, unit-conversion refactor, and derived metric documentation; adds/updates matching tests.
Accuracy accumulator keys
accuracy/accuracy_record_processor.py, accuracy_results_processor.py, models.py, metrics/types/accuracy_metrics.py, tests/unit/accuracy/*
Introduces underscore-namespaced transport keys, renames process_result to process_record, and adds console-group tagging.
RecordsManager routing/dispatch
records/records_manager.py, records_manager_processing.py, tests/unit/records/*
Builds a metadata-driven routing table and _dispatch_record fan-out replacing direct processor forwarding for metrics, telemetry, server metrics, network latency, and credit-phase events.
Legacy processor removal/rename
post_processors/metric_results_processor.py, record_export_results_processor.py, timeslice_metric_results_processor.py, otel_metrics_results_processor.py, record_export_jsonl_writer.py, network_latency/jsonl_writer.py, related tests
Deletes obsolete processor classes and renames entry points to process_record with finalize() hooks.
ProfileResults timeslices shape
common/models/record_models.py, tests/unit/common/models/test_record_models.py, _numeric_bounds_baseline.txt
Replaces the timeslice_metric_results dict field with the timeslices list.

Poem

A hop, a skip, past processors old,
Accumulators now take hold! 🐇
Records dispatch, routed with care,
Through tables built from metadata rare.
No more dotted tags to trip and fall—
Just process_record for one and all! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.25% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: removing legacy results processors and routing records by record type.
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.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unit/post_processors/test_metrics_accumulator.py (1)

27-28: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Annotate mock_run in this test module.

mock_run is a BenchmarkRun fixture, so the test methods should type it as BenchmarkRun instead of leaving it implicit.

🤖 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/unit/post_processors/test_metrics_accumulator.py` around lines 27 - 28,
Annotate the test methods’ mock_run fixture parameter as BenchmarkRun, importing
BenchmarkRun if needed; update the relevant tests in the metrics accumulator
module without changing fixture behavior.

Source: Coding guidelines

🧹 Nitpick comments (3)
tests/unit/common/models/test_record_models.py (1)

20-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Conform the updated tests to the repository test convention.

Add -> None and include the expected outcome in each test name.

Proposed naming and annotation update
-    def test_profile_results_with_timeslices(self):
+    def test_profile_results_timeslices_preserves_metric_lookup(self) -> None:

-    def test_profile_results_without_timeslices(self):
+    def test_profile_results_no_timeslices_defaults_to_none(self) -> None:

-    def test_profile_results_with_empty_timeslices(self):
+    def test_profile_results_empty_timeslices_preserves_empty_list(self) -> None:

-    def test_profile_results_with_multiple_timeslices_and_metrics(self):
+    def test_profile_results_multiple_timeslices_maps_metrics_by_tag(self) -> None:

As per coding guidelines, “Add type hints to all functions” and “Name tests as test_<function>_<scenario>_<expected>.”

Also applies to: 61-62, 80-81, 100-101

🤖 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/unit/common/models/test_record_models.py` around lines 20 - 21, Update
the affected test methods, including test_profile_results_with_timeslices and
the tests at the other referenced locations, to return-annotate with -> None and
rename each using test_<function>_<scenario>_<expected>, explicitly stating the
expected outcome.

Source: Coding guidelines

tests/unit/post_processors/test_timeslice_metric_results_processor.py (1)

21-23: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Annotate the mock_run fixture parameter.

The newly added tests leave mock_run untyped. Add its concrete fixture type consistently across these methods. As per coding guidelines, “Add type hints to all functions, including parameters and return values.”

Also applies to: 29-33, 35-36, 64-65, 87-88, 113-114, 141-142, 172-175, 183-186, 209-210

🤖 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/unit/post_processors/test_timeslice_metric_results_processor.py` around
lines 21 - 23, Annotate the mock_run parameter in all affected test methods,
including test_initialization_without_slice_duration_disables_timeslices, with
the concrete fixture type used by the mock_run fixture; keep the annotations
consistent across every listed test and preserve the existing return type hints.

Source: Coding guidelines

src/aiperf/accuracy/models.py (1)

11-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reduce redundant constant commentary.

Most of this block restates the constants and processing flow. Retain the collision rationale, but condense the “what” details.

As per coding guidelines, “Write comments only to explain ‘why’, not ‘what’; do not over-comment code.”

🤖 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/aiperf/accuracy/models.py` around lines 11 - 25, Condense the comments
above the accuracy constants to explain only the namespace-collision rationale.
Remove descriptions of emitted tags, processing flow, and record contents, while
retaining that transport keys use the accuracy_ prefix to avoid colliding with
accuracy. summary tags, particularly accuracy.unparsed.

Source: Coding guidelines

🤖 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 `@docs/plugins/plugin-system.md`:
- Around line 137-138: Update the plugin-category total in the introduction of
plugin-system.md from 33 to 32 so it matches the table entries after replacing
accumulator and stream_exporter.

In `@src/aiperf/metrics/types/network_adjusted_metrics.py`:
- Around line 11-14: The documentation around MetricsAccumulator and
_derive_value incorrectly states percentile, mean, and standard-deviation
invariants unconditionally. Clarify that these properties apply only when
shifted values remain nonnegative; note that adjusted values are clamped at zero
when RTT exceeds source latency, so clamping can alter the distributions.

In `@src/aiperf/records/records_manager.py`:
- Around line 535-549: Capture the errors returned by
_dispatch_record(record_data) and propagate them through the phase-level error
handling before calling _records_tracker.update_from_record_data(record_data).
Ensure metric-handler failures are included in
_error_tracker.increment_error_count_for_phase (or cause phase failure) so
records are not marked successfully processed when dispatching fails.

In `@tests/unit/gpu_telemetry/test_telemetry_integration.py`:
- Around line 272-277: Annotate the failing_process_telemetry_record replacement
coroutine with the same record parameter type and async return type as the
original process_telemetry_record method, preserving the existing behavior while
satisfying type checking.

---

Outside diff comments:
In `@tests/unit/post_processors/test_metrics_accumulator.py`:
- Around line 27-28: Annotate the test methods’ mock_run fixture parameter as
BenchmarkRun, importing BenchmarkRun if needed; update the relevant tests in the
metrics accumulator module without changing fixture behavior.

---

Nitpick comments:
In `@src/aiperf/accuracy/models.py`:
- Around line 11-25: Condense the comments above the accuracy constants to
explain only the namespace-collision rationale. Remove descriptions of emitted
tags, processing flow, and record contents, while retaining that transport keys
use the accuracy_ prefix to avoid colliding with accuracy. summary tags,
particularly accuracy.unparsed.

In `@tests/unit/common/models/test_record_models.py`:
- Around line 20-21: Update the affected test methods, including
test_profile_results_with_timeslices and the tests at the other referenced
locations, to return-annotate with -> None and rename each using
test_<function>_<scenario>_<expected>, explicitly stating the expected outcome.

In `@tests/unit/post_processors/test_timeslice_metric_results_processor.py`:
- Around line 21-23: Annotate the mock_run parameter in all affected test
methods, including
test_initialization_without_slice_duration_disables_timeslices, with the
concrete fixture type used by the mock_run fixture; keep the annotations
consistent across every listed test and preserve the existing return type hints.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: adf06611-66a8-45da-921b-35ac6e9ce52a

📥 Commits

Reviewing files that changed from the base of the PR and between e7d4339 and 17dabb5.

📒 Files selected for processing (68)
  • docs/accuracy/accuracy_stubs.md
  • docs/cli-options.md
  • docs/dev/patterns.md
  • docs/diagrams/metrics-flow.md
  • docs/plugins/plugin-system.md
  • docs/reference/list-metric-aggregation.md
  • src/aiperf/accuracy/accuracy_record_processor.py
  • src/aiperf/accuracy/accuracy_results_processor.py
  • src/aiperf/accuracy/models.py
  • src/aiperf/common/messages/inference_messages.py
  • src/aiperf/common/models/credit_models.py
  • src/aiperf/common/models/network_latency_models.py
  • src/aiperf/common/models/record_models.py
  • src/aiperf/common/models/server_metrics_models.py
  • src/aiperf/common/models/telemetry_models.py
  • src/aiperf/config/artifacts.py
  • src/aiperf/exporters/metrics_base_exporter.py
  • src/aiperf/gpu_telemetry/protocols.py
  • src/aiperf/metrics/accumulator.py
  • src/aiperf/metrics/base_aggregate_metric.py
  • src/aiperf/metrics/derived_sum_metric.py
  • src/aiperf/metrics/display_units.py
  • src/aiperf/metrics/network_adjusted_analyzer.py
  • src/aiperf/metrics/types/accuracy_metrics.py
  • src/aiperf/metrics/types/network_adjusted_metrics.py
  • src/aiperf/metrics/types/power_efficiency_metrics.py
  • src/aiperf/network_latency/accumulator.py
  • src/aiperf/network_latency/jsonl_writer.py
  • src/aiperf/network_latency/protocols.py
  • src/aiperf/orchestrator/search_planner/_pooled_percentile.py
  • src/aiperf/plugin/categories.yaml
  • src/aiperf/plugin/enums.py
  • src/aiperf/plugin/plugins.py
  • src/aiperf/plugin/plugins.yaml
  • src/aiperf/plugin/schema/plugins.schema.json
  • src/aiperf/post_processors/metric_results_processor.py
  • src/aiperf/post_processors/otel_metrics_results_processor.py
  • src/aiperf/post_processors/protocols.py
  • src/aiperf/post_processors/record_export_jsonl_writer.py
  • src/aiperf/post_processors/record_export_results_processor.py
  • src/aiperf/post_processors/strategies/core.py
  • src/aiperf/post_processors/timeslice_metric_results_processor.py
  • src/aiperf/records/records_manager.py
  • src/aiperf/records/records_manager_processing.py
  • src/aiperf/server_metrics/protocols.py
  • tests/unit/accuracy/test_accuracy_record_processor.py
  • tests/unit/common/models/test_record_models.py
  • tests/unit/exporters/conftest.py
  • tests/unit/gpu_telemetry/test_telemetry_integration.py
  • tests/unit/metrics/test_list_metric_aggregation.py
  • tests/unit/metrics/test_power_efficiency_metrics.py
  • tests/unit/network_latency/test_jsonl_writer.py
  • tests/unit/post_processors/conftest.py
  • tests/unit/post_processors/test_metric_results_processor.py
  • tests/unit/post_processors/test_metrics_accumulator.py
  • tests/unit/post_processors/test_network_adjusted_metrics.py
  • tests/unit/post_processors/test_otel_error_paths.py
  • tests/unit/post_processors/test_otel_metrics_results_processor.py
  • tests/unit/post_processors/test_post_processor_integration.py
  • tests/unit/post_processors/test_record_export_jsonl_writer.py
  • tests/unit/post_processors/test_record_export_jsonl_writer_detailed.py
  • tests/unit/post_processors/test_timeslice_metric_results_processor.py
  • tests/unit/property/_numeric_bounds_baseline.txt
  • tests/unit/records/test_records_manager.py
  • tests/unit/records/test_records_manager_network_latency.py
  • tests/unit/records/test_records_manager_process_results.py
  • tests/unit/records/test_records_manager_routing.py
  • tests/unit/server_metrics/test_accumulator.py
💤 Files with no reviewable changes (10)
  • src/aiperf/post_processors/metric_results_processor.py
  • src/aiperf/network_latency/protocols.py
  • src/aiperf/post_processors/timeslice_metric_results_processor.py
  • src/aiperf/post_processors/record_export_results_processor.py
  • tests/unit/exporters/conftest.py
  • tests/unit/property/_numeric_bounds_baseline.txt
  • src/aiperf/post_processors/record_export_jsonl_writer.py
  • src/aiperf/plugin/categories.yaml
  • src/aiperf/records/records_manager_processing.py
  • src/aiperf/plugin/schema/plugins.schema.json

Comment on lines +137 to +138
| `accumulator` | `AccumulatorType` | Record-type-routed aggregation and summary computation |
| `stream_exporter` | `StreamExporterType` | Record-type-routed streaming sinks such as JSONL and OpenTelemetry |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the plugin-category total.

These replacements leave 32 table entries, but the introduction still says 33. Update that count to prevent the reference from contradicting itself.

🤖 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 `@docs/plugins/plugin-system.md` around lines 137 - 138, Update the
plugin-category total in the introduction of plugin-system.md from 33 to 32 so
it matches the table entries after replacing accumulator and stream_exporter.

Comment on lines +11 to +14
known at the end of the run, so MetricsAccumulator injects the shifted distributions
after aggregation (subtracting a constant shifts every percentile and the mean by that
constant and leaves the standard deviation unchanged). ``_derive_value`` therefore
always defers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Document the clamping caveat.

The stated percentile/mean/std invariants are false when RTT exceeds a source latency: adjusted values are clamped at zero. Limit this claim to unclamped distributions.

🤖 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/aiperf/metrics/types/network_adjusted_metrics.py` around lines 11 - 14,
The documentation around MetricsAccumulator and _derive_value incorrectly states
percentile, mean, and standard-deviation invariants unconditionally. Clarify
that these properties apply only when shifted values remain nonnegative; note
that adjusted values are clamped at zero when RTT exceeds source latency, so
clamping can alter the distributions.

Comment on lines +535 to +549
await self._dispatch_record(record_data)
self._records_tracker.update_from_record_data(record_data)
if record_data.error:
self._error_tracker.increment_error_count_for_phase(
record_data.metadata.benchmark_phase, record_data.error
)

Per-handler exceptions are caught so one bad accumulator does not abort
the others. GPU telemetry / server metrics records are routed via their
own ``@on_pull_message`` handlers (and main's side-channel processors)
and do not flow through here.
"""
targets: list[object] = [
*self._metric_record_accumulators,
*self._metric_record_stream_exporters,
]
if not targets:
return
results = await asyncio.gather(
*[t.process_record(record_data) for t in targets],
return_exceptions=True,
)
for target, result in zip(targets, results, strict=True):
if isinstance(result, BaseException):
self.error(
f"Accumulator {target.__class__.__name__} failed for "
f"metric_records: {result!r}"
)
phase = record_data.metadata.benchmark_phase
if (
phase in self._complete_credit_phases
and self._records_tracker.check_and_set_all_records_received_for_phase(
phase
)
):
await self._handle_all_records_received(phase)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Preserve metric-handler failures before counting the record.

_dispatch_record() returns accumulator/exporter exceptions, but this path discards them and immediately marks the record processed. A failed metric accumulator can therefore yield incomplete metrics while completed advances and the phase error summary omits the failure. Record these errors in the phase-level error path, or fail the phase before updating the tracker.

🤖 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/aiperf/records/records_manager.py` around lines 535 - 549, Capture the
errors returned by _dispatch_record(record_data) and propagate them through the
phase-level error handling before calling
_records_tracker.update_from_record_data(record_data). Ensure metric-handler
failures are included in _error_tracker.increment_error_count_for_phase (or
cause phase failure) so records are not marked successfully processed when
dispatching fails.

Comment on lines +272 to +277
async def failing_process_telemetry_record(record):
if record.gpu_index == 0: # Fail on first GPU only
raise ValueError("Simulated processing error")
return await original_process(record)

faulty_processor.process_telemetry_record = failing_process_result
faulty_processor.process_telemetry_record = failing_process_telemetry_record

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Annotate the replacement coroutine.

failing_process_telemetry_record introduces untyped parameter and return contracts.

Proposed fix
-        async def failing_process_telemetry_record(record):
+        async def failing_process_telemetry_record(
+            record: TelemetryRecord,
+        ) -> None:
📝 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
async def failing_process_telemetry_record(record):
if record.gpu_index == 0: # Fail on first GPU only
raise ValueError("Simulated processing error")
return await original_process(record)
faulty_processor.process_telemetry_record = failing_process_result
faulty_processor.process_telemetry_record = failing_process_telemetry_record
async def failing_process_telemetry_record(
record: TelemetryRecord,
) -> None:
if record.gpu_index == 0: # Fail on first GPU only
raise ValueError("Simulated processing error")
return await original_process(record)
faulty_processor.process_telemetry_record = failing_process_telemetry_record
🤖 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/unit/gpu_telemetry/test_telemetry_integration.py` around lines 272 -
277, Annotate the failing_process_telemetry_record replacement coroutine with
the same record parameter type and async return type as the original
process_telemetry_record method, preserving the existing behavior while
satisfying type checking.

Source: Coding guidelines

@ilana-n ilana-n left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the records pipeline cleanup! This is great + much cleaner. Going to take some more time to understand whats going on but for now one comment about seperating phase exports

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This now phase-scopes only MetricsAccumulator; AccuracyResultsProcessor is also a metric_records accumulator in this PR, but it falls through to plain summarize(). Since AccuracyResultsProcessor.process_record() increments one global counter set for every record, warmup records are included in the profiling accuracy summary, and the warmup summary can include profiling records too. I reproduced this by feeding one correct warmup record and one incorrect profiling record: accuracy.overall came back as count=2/current=0.5 instead of the profiling-only count=1/current=0.0. Please either make accuracy implement a phase-scoped export path or store counts keyed by phase and summarize the requested phase here.

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.

3 participants