Stop NoncommutativeConvergence from retaining 270 GiB of Lévy area coefficients - #4044
Closed
ChrisRackauckas-Claude wants to merge 1 commit into
Closed
Conversation
…efficients The NoncommutativeConvergence group grew without bound (>51 GiB observed, no plateau) and could not pass on any runner. The cause is sim6's truncation parameter, not the solver. RKMilGeneral(p = true, dt = h) resolves the Levy area truncation via floor(c*h^(1-2*gamma)) + 1 = 1/h, which is the Kloeden-Platen Fourier rule (convorder 1/2). RKMilGeneral approximates the Levy area with MronRoe (convorder 1), so the terms actually needed for the requested accuracy eps = h^(3/2) are terms_needed(m=4, h=1/2^12, eps) = 12, not 4097. _z_prototype sizes the auxiliary noise increment to hold that many Fourier coefficients, norv(m, p) = 2mp + (m^2+m)/2, so p = 4097 makes dZ 32786 floats (262 KB) per step. analyticless_test_convergence with use_noise_grid = false keeps every trajectory's reference noise reachable for the whole study -- appxtrue's build_solution carries sol.W, a NoiseWrapper whose .source is the reference NoiseProcess -- so the reference grid is never released. Measured retention, replicating the inner loop over 3 iterations: p = true, dt = 1/2^12 0.5398 GiB/trajectory -> 269.9 GiB over 500 RKMilGeneral() 0.0019 GiB/trajectory -> 0.9 GiB over 500 Dropping p = true uses the automatic truncation and does not weaken the test. Strong order over 7 seeds, 500 trajectories, reference dt = 1/2^12: seed 100 1 42 2718 31415 7 999 order 0.945 0.942 0.952 0.925 0.919 0.946 0.951 All within |order - 1| < 0.082, against the existing 0.2 tolerance. For comparison the p = true form needs 145 s and peaks at 18.3 GiB for only 25 trajectories, which is why it was killed on the 16 GB pool. The group ran on self-hosted 8vcpu/16gb: 7/7 pass, 3m34.6s for the test body, 12m50s wall including test-env precompilation, 5.94 GiB peak RSS. Repoint the group off the high-memory label (which no runner in the fleet carries, so the job never scheduled -- see SciML#4030) onto the standard self-hosted pool, and drop the timeout from 240 to 60 minutes. The OOPWeakConvergence / IIPWeakConvergence groups remain pinned to high-memory. Those fail for a different reason -- test_convergence retains all 5e5 x 5 solution objects, ~5.4 GiB per study with two such studies live at once -- and are left for a separate change. Fixes SciML#4036 Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013WW2jGeoWZVZu7AiscUNSz
This was referenced Jul 28, 2026
Member
Author
|
Superseded by #4038, which landed the same Rebasing this branch would now do more harm than good. Relative to current master it would:
Closing as superseded. The measurements from the investigation are in #4036 (comment) and remain valid for the weak-convergence groups, which #4038 does not touch. |
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.
Fixes #4036.
What was wrong
NoncommutativeConvergencegrew linearly without plateau (>51 GiB observed, stopped there, no known ceiling) and could not pass on any runner in the fleet. The cause issim6's Lévy-area truncation parameter, not a solver leak.RKMilGeneral(p = true, dt = h)resolves the truncation aswhich is the Kloeden–Platen Fourier rule (
convorder = 1/2).RKMilGeneralapproximates the Lévy area with MronRoe (convorder = 1), so the terms actually needed for the requested accuracyε = h^(3/2)are far fewer:_z_prototypesizes the auxiliary noise increment to holdnorv(m, p)coefficients, sop = 4097makesdZ32786 floats = 262 KB per step. The reference solve is 2049 steps → 0.5 GiB of savedZ.That 0.5 GiB is then retained per trajectory.
analyticless_test_convergencewithuse_noise_grid = falsestoresappxtrue(sol, true_sol)for every(trajectory, dt), andappxtrueends inbuild_solution(sol, …), which carriessol.W— aNoiseWrapperwhose.sourceis the referenceNoiseProcess. Nothing is released until all 500 trajectories finish.Measured retention, replicating the inner loop verbatim (Julia 1.12.4, single thread):
RKMilGeneral(p = true, dt = 1/2^12)RKMilGeneral()Confirming it is
pand nothing else:save_noise = falseon the coarse solves changes retention by 0.0% (aNoiseWrapper-driven solve never stored its ownW/Z), and the other sims in the file retain 0.063 / 0.065 / 0.222 GiB.The change
Drop
p = true, dt = test_dt_miland use the automatic truncation. Referencedtand trajectory count are unchanged, so the study itself is the same; only the Lévy-area term count changes, from 341× over-provisioned to what the accuracy target asks for.Verification
Strong order across 7 seeds at 500 trajectories, reference
dt = 1/2^12:𝒪est[:final]|𝒪 - 1|All pass the existing
< 0.2tolerance with ≥2.4× margin; the tolerance is untouched. (The seed matters becausesim1–sim5consume draws beforesim6, so the effective seed there is not pinned by the file'sRandom.seed!(100).)Full group run,
ODEDIFFEQ_TEST_GROUP=NoncommutativeConvergence,self-hosted 8vcpu/16gb:For contrast, the current
p = trueform needs 145 s and peaks at 18.3 GiB for only 25 trajectories — which is why job 89959748664 lost the runner at 28 min on the 16 GB pool.CI config
The group was pinned to a
high-memorylabel that no runner in the fleet carries, so it never scheduled and held the wholeSublibrary CIrun open (#4030). With the memory bounded at ~6 GiB it can go on the standard self-hosted pool, and the 240-minute timeout drops to 60 (≈17× headroom over the measured 3m35s test body, ≈4.7× over the 12m50s including precompilation).Deliberately not in this PR
p == trueformula itself. It hands you the Fourier truncation for an algorithm that no longer uses the Fourier expansion. Deriving it fromterms_neededfor the algorithm in use would be a solver behavior change and wants its own PR and tests._z_prototype'sp === nothingbranch guessesmax(10, m)rather than callingterms_needed, becausedtis not in scope there. Ath = 1/2^12that gives 10 where 12 is wanted — a ~18% overshoot of the error target, visible as the order landing near 0.92–0.95 rather than 1.0. Fixing it properly means threadingdtinto_z_prototype, which is exported from StochasticDiffEqCore.build_solutioninappxtruecarriesprob/Wthatcalculate_ensemble_errorsnever reads. Fixing that would stop any caller from pinning reference noise, not just this one. This PR only removes the 300× multiplier in front of it.OOPWeakConvergence/IIPWeakConvergencestay pinned tohigh-memory. They fail for a different reason —test_convergenceretaining all5e5 × 5solution objects, measured 2.3 KiB each ≈ 5.4 GiB per study, with two studies live at once at global scope. Bounded, unlike this one, but past 16 GB. Separate change.Links
🤖 Generated with Claude Code
https://claude.ai/code/session_013WW2jGeoWZVZu7AiscUNSz