Commit 938dae5
Share the SROCK tableau vectors instead of rebuilding them per cache (#4050)
SROCK2ConstantCache, TangXiaoSROCK2ConstantCache, KomBurSROCK2ConstantCache and
SROCKC2ConstantCache each built `recf` -- a 4476-element Vector{Float64}, 35 KiB
-- as an array literal inside the constructor, so every integrator allocated its
own copy of a compile-time constant table. SKSROCKConstantCache did the same with
199 BigFloat literals for `mc` and `mα`.
Nothing mutates these tables; the perform_step! methods only index them. Hoisting
them to module-level consts lets every cache share one copy. `convert(Vector{T},
...)` returns its argument unchanged when the element type already matches, so
Float64 solves share the table and other element types convert exactly as the
struct constructor did before.
This is not only a test-suite concern: an SDE solution retains its cache through
the `interp` field, so every retained trajectory of an SROCK ensemble was
carrying its own 35 KiB tableau.
Per-solution retention in an ensemble (2000 trajectories, scalar linear SDE,
save_everystep = false):
SROCKC2 iip 38.72 -> 3.72 KiB SROCK2 iip 40.63 -> 4.15 KiB
SROCKC2 oop 37.59 -> 2.59 KiB SROCK2 oop 39.44 -> 2.96 KiB
SimplifiedEM (control, untouched) 2.25 -> 2.25 KiB
Allocation per cache construction:
SROCK2 39368 -> 1760 bytes SROCKC2 37208 -> 1296
TangXiaoSROCK2 39192 -> 1616 bytes KomBurSROCK2 40224 -> 1296
SKSROCK 45024 -> 3488 bytes
SKSROCK keeps the allocation win (398 BigFloats are no longer constructed per
cache) but not the sharing one, since converting BigFloat to the cache element
type necessarily allocates.
The change is pure code motion. Verified:
- The multiset of all 19329 numeric literals in the file is unchanged.
- `git diff -w` is 382 lines; the rest of the diff is the 4-space de-indent
from moving the literals out of the function bodies.
- Solver output is bitwise identical on 32 cases -- SROCK1, SROCK2, SROCKEM,
SKSROCK, SROCKC2, TangXiaoSROCK2 (versions 1 and 5) and KomBurSROCK2, each
in-place and out-of-place, at dt = 1/2^5 and 1/2^7, comparing every saved
state with `==`.
- GROUP=Core tests pass (2m19s, exit 0), Runic clean.
Claude-Session: https://claude.ai/code/session_013WW2jGeoWZVZu7AiscUNSz
Co-authored-by: ChrisRackauckas-Claude <accounts@chrisrackauckas.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>1 parent 8037f9f commit 938dae5
1 file changed
Lines changed: 18705 additions & 18687 deletions
0 commit comments