k4bench.regression.common_mode¶
k4bench.regression.common_mode ¶
Split a run group's nightly movement into a group-wide part and a per-config part.
A sweep benchmarks one detector as many configurations of itself, all on one host, in one job, against one software stack. When that shared context moves, every configuration moves with it, and the step detector — which judges each configuration independently — reports the same event once per configuration. The finding is right and the arithmetic is right; the presentation is wrong, and the volume buries whatever else the night found.
This module answers the question the run group can answer and a single series cannot: how much of tonight's move was shared? For each metric it computes one number per run, the group's common-mode shift, and divides it out of each configuration's series. What remains is that configuration's own movement.
The shift is judged as its own series rather than discarded. That distinction is the whole design:
- Subtracting it would erase a stack-wide regression — the case where every configuration really did get slower — which is a genuine loss of sensitivity.
- Judging it makes the detector more sensitive to that case, not less: the
shift is a median over the whole group, so its noise falls by roughly
sqrt(n_configs), and a shared change clears the gates sooner than it does when it has to clear them separately in every configuration.
What the reader gets is one finding for a shared move and one finding for a configuration that moved on its own, instead of the two being indistinguishable piles of the same row.
The decomposition only ever happens when the group really did move together:
one configuration holding its historical level vetoes it outright (see
:data:MIN_UNANIMITY). A run group is not a poll, and a majority that moved is
not a common mode — on a removal sweep the majority is exactly what a
detector-local regression produces.
is_common_mode ¶
pretty_config ¶
Human-readable configuration label, for the one label that is not a configuration. Anything else is returned unchanged.
format_shift ¶
A common-mode factor as display text (×1.204), never a unit.
Source code in k4bench/regression/common_mode.py
common_mode_shifts ¶
Per-run group-wide shift factors for metric, as {run_id: factor}.
df is a run group's long-form trend frame (run_id, label, and
metric), already restricted to the rows that may be judged.
Each configuration is first divided by its own median over the window, which removes the fact that configurations sit at wildly different absolute levels and leaves a series centred on 1.0. The shift for a run is then the median of those ratios across configurations — a robust estimate that a handful of configurations moving on their own cannot drag.
Normalising by a window median uses runs from both sides of each night, which would be illegitimate if this were a detection statistic. It is not: it removes a per-configuration scale, a quantity that does not depend on time, and the comparison that decides anything is always across configurations within one run.
A run appears in the result when enough configurations contributed
(:data:MIN_COMMON_MODE_CONFIGS) and they agree about what happened: a
shift worth speaking of has to carry every configuration with it
(:data:MIN_UNANIMITY), while a run that simply sat at its usual level is
recorded as the ~1.0 it measured.
A missing run is not a measured 1.0. It is the absence of a common-mode
measurement — too few configurations to ask, or configurations that
disagreed — and the two must not be confused, because 1.0 is a claim that
the group held still. Callers divide by 1.0 for such runs
(:func:residuals) and judge every series exactly as measured.
Source code in k4bench/regression/common_mode.py
residuals ¶
values with each run's common-mode shift divided out.
Division rather than subtraction because the shift is a ratio: a host or stack that costs 3 % more costs it in proportion, and the configurations of one sweep span a wide range of absolute levels, over which a single additive offset would mean nothing.
Source code in k4bench/regression/common_mode.py
shift_history ¶
shift_history(shifts: dict[str, float], run_dates: dict[str, object], reliability: dict[str, bool | None], workloads: dict[str, int] | None = None) -> DataFrame
The group-wide shift as a history frame the engine can walk.
Shaped exactly like a configuration's own history — run_id,
run_date, value, reliable, and the workload each run simulated
— because it is one: a series centred on 1.0 whose steps are shared moves
of the whole run group, judged by the same gates as everything else.
Only the runs :func:common_mode_shifts actually measured appear. A run it
left out is a gap in this series, never a 1.0: "the group moved by nothing"
is a measurement, and that run did not make it.