Skip to content

perf: fast mode = AFTER_GENERATOR tap control + reassessment de-tax (0.3.0.post1)#117

Merged
marota merged 4 commits into
ainetus:mainfrom
marota:claude/fast-mode-after-generator-tap-control
Jul 8, 2026
Merged

perf: fast mode = AFTER_GENERATOR tap control + reassessment de-tax (0.3.0.post1)#117
marota merged 4 commits into
ainetus:mainfrom
marota:claude/fast-mode-after-generator-tap-control

Conversation

@marota

@marota marota commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

Release 0.3.0.post1 — makes the per-action reassessment fast on large grids (French 400 kV) without the accuracy loss the old fast mode carried, and stops the parallel path from paying a per-worker tax that fast per-action load flows can no longer amortize.

Root cause was traced knob-by-knob: 100 % of the slow/fast load-flow gap on the France grid is transformer_voltage_control_on running in the provider-default incremental outer loop (~57 Newton iters, ~4.6 s/LF). Switching only the tap-changer control mode recovers it at full accuracy.

Changes

  • run_load_flow(fast=True) redefined. No longer disables transformer/shunt voltage control (which shifted branch currents). Keeps tap regulation on but runs the tap-changer outer loop in AFTER_GENERATOR_VOLTAGE_CONTROL: one post-contingency AC LF drops ~57 → ~20 Newton iters (~4.6 s → ~0.7 s) for the same constrained-line current (225.6 A vs 226.2 A, 0.3 %). Slow mode (fast=False) keeps the incremental loop as the max-fidelity fallback.
  • PYPOWSYBL_FAST_MODE defaults to True (fast mode is now accuracy-preserving).
  • SimulationEnvironment._ensure_valid_state runs fast=True — the per-worker baseline LF only establishes a converged state, so the slow solve was pure waste: ~4.6 s → ~0.7 s per worker.
  • _should_parallelize_reassessment is fast-mode aware — in auto mode it stays serial until n_actions >= workers * _FAST_MODE_MIN_ACTIONS_PER_WORKER (6), because cheap fast LFs don't amortize the ~9 s/worker network-clone + baseline tax. Slow mode and the explicit REASSESSMENT_PARALLEL=True force are unchanged.

Result

France P.SAOL31RONCI, 15 actions, fast mode: auto now selects serial and the assessment lands at ~21 s (~1.4 s/action) with no env var (was 38–90 s). A memory-bandwidth-limited host paying ~38 s for 10 concurrent 118 MB clones is the biggest winner.

Compatibility

Fully backwards-compatible — no public API change; run_analysis(...) returns the same AnalysisResult shape. Behaviour differs only in the LF solver mode (fast mode preserves currents instead of changing them) and the auto parallel/serial decision under fast mode.

Tests

tests/test_reassessment_parallel_gate.py — new TestFastModeGate (fast-mode serial gate, many-actions escape hatch, force-parallel override, below-core-threshold). Full recommender suite delta: +4 passing, no new failures (pre-existing failures are unrelated missing-test-data deletions).

Release notes

docs/release-notes/v0.3.0.post1.md + CHANGELOG § 0.3.0.post1.

All commits are DCO signed-off (Signed-off-by: Antoine Marot <amarot91@gmail.com>).

🤖 Generated with Claude Code

Antoine Marot and others added 4 commits July 8, 2026 15:03
… iters)

Redefine "fast mode" for the pypowsybl backend. It no longer disables
transformer/shunt voltage control; it keeps tap regulation on but runs the
tap-changer outer loop in AFTER_GENERATOR_VOLTAGE_CONTROL.

On the full France grid, one post-contingency AC load flow with the default
incremental tap-control loop needs ~57 Newton iterations (~4.6s); after-generator
converges in ~20 (~0.7s) for the same constrained-line current (<0.5% delta).
This cuts the per-action reassessment (one LF per prioritized action) ~5x while
retaining the tap-regulation accuracy the old fast mode (tap control off) gave up.

- network_manager.run_load_flow(fast=True): set provider
  transformerVoltageControlMode=AFTER_GENERATOR_VOLTAGE_CONTROL instead of
  transformer_voltage_control_on / shunt_compensator_voltage_control_on = False.
- config.PYPOWSYBL_FAST_MODE default False -> True.
- refresh the stale "no voltage control" docstrings (observation, overflow_analysis).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Antoine Marot <amarot91@gmail.com>
The parallel per-action reassessment clones the full network per worker and
builds a fresh SimulationEnvironment each — whose _ensure_valid_state ran a
SLOW baseline load flow. On the France grid that per-worker tax measured
~9s (118MB clone + ~4.6s slow baseline LF), which DOMINATES the parallel path;
with fast (AFTER_GENERATOR) per-action LFs it is never amortized for realistic
prioritized-action counts, so parallel was ~2x slower than serial on a
memory-bandwidth-limited host (assessment 38s vs ~21s serial).

Two fixes:
- SimulationEnvironment._ensure_valid_state now runs fast=True. It only
  establishes a converged baseline state (the accuracy-critical per-action
  re-sims run their own LFs), and after-generator keeps the same currents, so
  the slow incremental solve was pure waste: ~4.6s -> ~0.7s per worker.
- _should_parallelize_reassessment now takes fast_mode: in auto mode it stays
  SERIAL until n_actions >= workers * _FAST_MODE_MIN_ACTIONS_PER_WORKER (6),
  because cheap fast LFs don't amortize the per-worker clone+baseline tax.
  Slow mode and the explicit REASSESSMENT_PARALLEL=True force are unchanged.

End-to-end (France P.SAOL31RONCI, 15 actions, fast mode): auto now picks serial,
assessment ~21s (~1.4s/action) with no env var. +4 gate tests; full suite delta
is +4 passing, no new failures.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Antoine Marot <amarot91@gmail.com>
Bump version 0.3.0 -> 0.3.0.post1, CHANGELOG + release notes for the
fast-mode (AFTER_GENERATOR tap control) redefinition and the fast-mode-aware
reassessment parallelism gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Antoine Marot <amarot91@gmail.com>
…README)

Update the backend-simulation docs to match the v0.3.0.post1 redefinition:
fast mode keeps transformer/shunt voltage control ON and only switches the
tap-changer outer loop to AFTER_GENERATOR_VOLTAGE_CONTROL (same currents,
~6-7x fewer iters) instead of disabling control. Also: PYPOWSYBL_FAST_MODE
default now True, _ensure_valid_state runs fast, and the fast-mode-aware
reassessment serial gate. Historical (pre-0.3.0.post1) behaviour noted inline.

- docs/architecture/simulation-pipeline.md: §3.1 knob table, §3.3 rewrite,
  §3.6 cap note, §3.7 sequence, §6 default + reassessment-gate note,
  §9 cheat-sheet, §10 cross-refs.
- README.md: "Fast simulation mode" note.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Antoine Marot <amarot91@gmail.com>
@marota marota merged commit 9baa9c2 into ainetus:main Jul 8, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant