Add precompilation workload to reduce first-call latency - #417
Draft
jd-lara wants to merge 3 commits into
Draft
Conversation
Run the core solve paths at precompile time on a tiny hand-built 4-bus system (REF/PV/PQ/PQ; Source, ThermalStandard, PowerLoads, ZIP StandardLoad, meshed Lines) so first-call latency moves into the cached pkgimage build. The fixture is constructed purely from PSY constructors in memory: no PowerSystemCaseBuilder, no file parsing, and no deserialization cost at precompile time. Workload coverage (Tier 1): PowerFlowData construction + in-place polar NR solve (twice, to compile the PolarNRCache reuse path), the one-shot DataFrame results API, DCPowerFlow, and PTDFDCPowerFlow. Measured on Julia 1.12.6 (Linux x86_64): first AC solve 13.1 s -> 0.07 s, first DC solve 3.4 s -> 0.013 s, first PTDF solve 1.0 s -> 0.001 s, load time 3.3 s -> 3.9 s; one-time Pkg.precompile cost 11.6 s -> 135 s and pkgimage 3.9 MB -> 58.7 MB. Developers can opt out per PrecompileTools convention via the "precompile_workload" preference. The new internal docstring is registered in the internals autodocs page to keep the strict docs build green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXkkoqjT6CejCV2AbnhTiP
jd-lara
marked this pull request as draft
July 24, 2026 13:00
Cover the most-used solver set in the precompilation workload: polar NR (already present), TrustRegionACPowerFlow (new; compiles the dogleg/TR driver and the TR-typed PowerFlowData chain), and the DC family (ABA and PTDF, already present). Per review direction, precompilation does not need converged power flows: the iterative workload solves now run with maxIterations = 2, which exercises the same iteration machinery (step, refinement, Jacobian refresh, and the non-convergence writeback) without paying for convergence. Two carve-outs: the one-shot NR call stays uncapped because write_results only executes on a converged solve, and capped runs end NaN-overwritten (OVERWRITE_NON_CONVERGED), so clear_injection_data! resets state before the cache-reuse solves to keep NaNs out of the KLU factorizations at precompile time. Measured (Julia 1.12.6, Linux x86_64): TR first solve 3.9 s -> 0.06 s; NR/DC/PTDF first solves unchanged (0.07 s / 0.015 s / 0.001 s); load time unchanged (~4 s); one-time Pkg.precompile 135 s -> 165 s; pkgimage 58.7 -> 61.1 MB. The Q-limit retry path needs no workload entry - it is already inferred transitively (first solve with check_reactive_power_limits = true measures 0.001 s). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXkkoqjT6CejCV2AbnhTiP
Precompile the common power-flow methods so first-call latency moves into the cached pkgimage: - Polar NR and Trust Region: one-shot solve plus in-place solve_power_flow! (2 capped iters, reset and resolve) to warm the cache-reuse hot path. - FastDecoupled variants: FDDecoupled/XB default and FDFixedJacobian. - Rectangular current-injection NR (2 capped iters). - DC ABA direct solve: one-shot plus in-place build-and-reuse. Exclude PTDF: uncommon, and its factorization adds build cost without lowering first-call latency. Drop the internal-fixture autodocs entry. Measured first-call: TR 2.13s to 0.017s, FD 2.12s to 0.064s, FD-fixed 5.25s to 0.017s, rectangular 3.47s to 0.072s; about +3s precompile.
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
Adds a precompilation workload that exercises the core AC and DC power-flow solve paths at package build time, moving first-call latency from user sessions into the cached package image.
Key Changes
New
src/precompile.jl: Defines a minimal in-memory test system (4 buses, mixed component types covering REF/PV/PQ partitions) and aPrecompileTools.@compile_workloadblock that exercises:PowerFlowDataconstruction + in-place solve (twice, to compile cache refresh/reuse paths)Exposed
_precompilation_workload_system(): Plain function so the test suite can exercise the exact workload inputs and validate precompilation coverageUpdated
src/PowerFlows.jl: Addedimport PrecompileToolsand includedprecompile.jllast (after all solve paths are defined)Updated
Project.toml: AddedPrecompileToolsdependency (compat1.2)Updated
docs/src/reference/api/internal_solvers.md: Added documentation section for the precompilation workloadImplementation Details
The workload is designed to:
PowerFlowData+ in-place solve, plus one-shot API)https://claude.ai/code/session_01EXkkoqjT6CejCV2AbnhTiP