perf: fast mode = AFTER_GENERATOR tap control + reassessment de-tax (0.3.0.post1)#117
Merged
marota merged 4 commits intoJul 8, 2026
Conversation
… 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_onrunning 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 inAFTER_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_MODEdefaults toTrue(fast mode is now accuracy-preserving).SimulationEnvironment._ensure_valid_staterunsfast=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_reassessmentis fast-mode aware — in auto mode it stays serial untiln_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 explicitREASSESSMENT_PARALLEL=Trueforce 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 sameAnalysisResultshape. 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— newTestFastModeGate(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