k4bench.regression.regions¶
k4bench.regression.regions ¶
Where inside the detector a timing step landed.
A confirmed run-level regression is one number, and one number names no
mechanism: "ALLEGRO got 21% slower" and "the HCAL barrel got fourteen times
slower while everything else stood still" are the same measurement, but only the
second can be matched against a diff. The k4BenchRegionTimingAction plugin
records per-event time per top-level detector region on every run, so the second
form is already measured — it has simply never been read by anything that
attributes a regression.
This module reads it: for one benchmark configuration and one change window, how each region's per-event time differs between the two ends the change entered between — the two releases, or the window's two runs when one release holds both. It judges nothing (the engine has already decided that the metric stepped) and it introduces no thresholds of its own; it reports the decomposition, largest movement first, and leaves the reading to whoever asked.
Two costs shape the implementation. Region files are per configuration and hold per-event arrays, so loading a whole trend window across every label is expensive — this loads exactly the two ends of one window, for one label, and only when something actually regressed there. And a release that recorded no region file is absent, never zero: a region that appears on one side of a window only is a real event (a detector added, removed or renamed) and must stay distinguishable from one that stood still.
The same files also carry each event's wall time and how much of it was spent
in stepping, which is the other half of the question: whether the step is in
the typical event or in a handful of long ones (:func:region_evidence). Both
readings come from one read of each file.
dirs_by_release ¶
Group run directories by the release they measured, keyed exactly as the
engine keys releases (:func:~k4bench.regression.engine.release_key), so a
window's ends match the verdict that named them.
Source code in k4bench/regression/regions.py
region_evidence ¶
region_evidence(run_dirs: Sequence[str], *, label: str, base_release: str, onset_release: str, base_run_id: str | None = None, onset_run_id: str | None = None, limit: int = MAX_REGIONS, judgeable_configs: set[tuple[str, str]] | None = None) -> tuple[tuple[RegionDelta, ...], EventProfile | None]
How each region's per-event time moved across (base, onset], largest
movement first, and the per-event wall times at both ends
(:class:~k4bench.regression.models.EventProfile).
Returns ((), None) when either end recorded no region timing at all —
with only one side measured there is no comparison to make, and inventing
one (treating the missing side as zero) would report every region of the
detector as newly appearing. The profile is likewise None unless both
ends recorded per-event wall times. When judgeable_configs is supplied,
failed or orphaned config-nights absent from that set are gaps and do not
enter either end.
A window whose ends name one release is two runs of that release, and base_run_id / onset_run_id are what tell them apart — the same pair the verdict, the email's window token and the blame range are identified by. The ends are then those two runs rather than the release's pool, because one pool measured against itself is not a comparison and would report every region as having stood still. Without a resolvable run on each side there is again nothing to compare.
Source code in k4bench/regression/regions.py
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | |
region_deltas ¶
region_deltas(run_dirs: Sequence[str], *, label: str, base_release: str, onset_release: str, base_run_id: str | None = None, onset_run_id: str | None = None, limit: int = MAX_REGIONS, judgeable_configs: set[tuple[str, str]] | None = None) -> tuple[RegionDelta, ...]
The region half of :func:region_evidence alone.