Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -874,8 +874,9 @@ AGENTIC_REPLAY only: upper bound (inclusive) on the random start position within

#### `--burst-phase-starts`

AGENTIC_REPLAY only: collapse the WARMUP-start and PROFILING-start dispatches into synchronized bursts instead of spreading them by each request's recorded offset from t*. By default (False) the phase starts are SPREAD: WARMUP requests are aligned globally so every trajectory reaches its t* at the same instant (the warmup end), and each lane's first PROFILING request waits out its recorded gap after t* -- reproducing the recorded arrival pattern at both phase boundaries. The rest of the replay (inter-turn delays) is timing-faithful regardless of this flag; it governs ONLY the burst-vs-spread of the two phase starts. Pass --burst-phase-starts to fire each phase's first requests together (faster concurrency ramp, synchronized start), e.g. for a throughput-oriented run rather than a faithful arrival replay.
AGENTIC_REPLAY only: collapse the WARMUP-start and PROFILING-start dispatches into synchronized bursts instead of spreading them by each request's recorded offset from t*. By default (True) the phase starts are BURST so configured concurrency becomes active inside the benchmark window. When False, WARMUP requests are aligned globally so every trajectory reaches its t* at the same instant (the warmup end), and each lane's first PROFILING request waits out its recorded gap after t*. The rest of the replay (inter-turn delays) is timing-faithful regardless of this setting; it governs ONLY the burst-vs-spread behavior at the two phase starts.
<br/>_Flag (no value required)_
<br/>_Default: `True`_

#### `--concurrency` `<str>`

Expand Down
20 changes: 9 additions & 11 deletions src/aiperf/common/config/loadgen_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,22 +262,20 @@ def parse_concurrency_list(
description="AGENTIC_REPLAY only: collapse the WARMUP-start and "
"PROFILING-start dispatches into synchronized bursts instead of "
"spreading them by each request's recorded offset from t*. By "
"default (False) the phase starts are SPREAD: WARMUP requests are "
"aligned globally so every trajectory reaches its t* at the same "
"instant (the warmup end), and each lane's first PROFILING request "
"waits out its recorded gap after t* -- reproducing the recorded "
"arrival pattern at both phase boundaries. The rest of the replay "
"(inter-turn delays) is timing-faithful regardless of this flag; "
"it governs ONLY the burst-vs-spread of the two phase starts. Pass "
"--burst-phase-starts to fire each phase's first requests together "
"(faster concurrency ramp, synchronized start), e.g. for a "
"throughput-oriented run rather than a faithful arrival replay.",
"default (True) the phase starts are BURST so configured concurrency "
"becomes active inside the benchmark window. When False, WARMUP "
"requests are aligned globally so every trajectory reaches its t* "
"at the same instant (the warmup end), and each lane's first "
"PROFILING request waits out its recorded gap after t*. The rest "
"of the replay (inter-turn delays) is timing-faithful regardless "
"of this setting; it governs ONLY the burst-vs-spread behavior at "
"the two phase starts.",
),
CLIParameter(
name=("--burst-phase-starts",),
group=Groups.LOAD_GENERATOR,
),
] = False
] = True

concurrency: Annotated[
Any, # CLI accepts string, validator converts to Union[int, list[int], None]
Expand Down
39 changes: 17 additions & 22 deletions src/aiperf/timing/strategies/agentic_replay.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
not reproduced. This includes parents gated on a child join (they sent turn
n-1 before t* and resume at the join turn during PROFILING, so n-1 warms that
turn). Streams whose first request is at/after t* (``next_turn_index == 0``)
have nothing to warm. By default the priming
requests are SPREAD -- aligned globally on t* so every trajectory's t* lands
at the warmup end (see ``_execute_warmup``); ``--burst-phase-starts`` fires
them all at once instead. The phase exits via the standard
have nothing to warm. By default the priming requests BURST together so the
configured lanes become active inside the benchmark window. When
``burst_phase_starts`` is false, requests are spread and aligned globally on
t* so every trajectory's t* lands at the warmup end (see ``_execute_warmup``).
The phase exits via the standard
``SendingCompleteStopCondition`` plus ``grace_period_sec=inf`` semantics
already in CreditPhaseConfig (count-driven: every turn-n-1 must return).

Expand All @@ -36,9 +37,10 @@
degraded trajectory pool.

PROFILING: each stream resumes at its first turn at/after t*
(``next_turn_index``). Default dispatch preserves the stream's recorded offset
from the replay boundary; ``--burst-phase-starts`` collapses each lane's first
eligible request to profiling-time 0. Accelerated cache warmup synthesizes a
(``next_turn_index``). Default dispatch collapses each lane's first eligible
request to profiling-time 0. When ``burst_phase_starts`` is false, dispatch
preserves the stream's recorded offset from the replay boundary. Accelerated
cache warmup synthesizes a
new replay boundary at the warmup handoff and carries each live stream's
residual next-turn delay into profiling, so the handoff ramps instead of
firing every live stream at once. Subsequent turns honor trace inter-turn
Expand Down Expand Up @@ -210,13 +212,8 @@ def __init__(
self._benchmark_id: str = (
user_config.benchmark_id if user_config is not None else "unknown"
)
# ``--burst-phase-starts`` (loadgen.burst_phase_starts). Default False:
# the WARMUP and PROFILING phase starts are SPREAD by each request's
# recorded offset from t* (warmup globally t*-aligned, profiling
# preserving each lane's leading gap). When True, both phase starts
# collapse into synchronized bursts. Governs ONLY the two phase-start
# dispatch patterns; the rest of replay timing is faithful regardless.
# ``is True`` guards MagicMock/None test configs -> default (spread).
# Real loadgen configs default to burst. Missing/mocked configs retain
# the spread fallback used by isolated strategy callers.
loadgen = getattr(user_config, "loadgen", None)
self._burst_phase_starts: bool = (
getattr(loadgen, "burst_phase_starts", False) is True
Expand Down Expand Up @@ -1429,14 +1426,12 @@ async def _dispatch_snapshot_for_profiling(
Each stream profiles from turn ``next_turn_index`` (the first turn at
or after t*; its predecessor, if any, was primed during WARMUP).

Dispatch anchoring depends on ``--burst-phase-starts``: by default
(spread) ``t0_offset = 0`` so each stream waits out its recorded offset
from t* -- the leading t*->first-request gap is preserved and lanes
ramp in. With ``--burst-phase-starts`` the trajectory's earliest
post-t* request is anchored at profiling-time 0 (subtracting T0, the
min offset) so the lane bursts at once. Relative timing among the
trajectory's streams and turns is identical either way -- only the
per-lane start offset differs.
By default, the trajectory's earliest post-t* request is anchored at
profiling-time 0 so every lane starts together. When
``burst_phase_starts`` is false, ``t0_offset = 0`` and each stream waits
out its recorded offset from t*. Relative timing among the trajectory's
streams and turns is identical either way -- only the per-lane start
offset differs.

Gated parents (``waiting_on_children``) are not dispatched here; their
join is seeded with the orchestrator and their gated turn fires when
Expand Down
Loading