1+ using OrdinaryDiffEqBDF
2+ using OrdinaryDiffEqCore
3+ using AllocCheck
4+ using Test
5+
6+ """
7+ Allocation tests for OrdinaryDiffEqBDF solvers using AllocCheck.jl.
8+ These tests verify that the step! operation should not allocate during stepping.
9+ Currently, many BDF solvers are allocating and marked with @test_broken.
10+ """
11+
12+ @testset " BDF Allocation Tests" begin
13+ # Test problem for standard ODE BDF methods
14+ function simple_system! (du, u, p, t)
15+ du[1 ] = - 0.5 * u[1 ]
16+ du[2 ] = - 1.5 * u[2 ]
17+ end
18+ prob = ODEProblem (simple_system!, [1.0 , 1.0 ], (0.0 , 1.0 ))
19+
20+ # Split problem for IMEX methods
21+ function f1! (du, u, p, t)
22+ du[1 ] = - 0.5 * u[1 ]
23+ du[2 ] = 0.0
24+ end
25+ function f2! (du, u, p, t)
26+ du[1 ] = 0.0
27+ du[2 ] = - 1.5 * u[2 ]
28+ end
29+ split_prob = SplitODEProblem (f1!, f2!, [1.0 , 1.0 ], (0.0 , 1.0 ))
30+
31+ # DAE problem for DAE solvers
32+ function dae_f! (resid, du, u, p, t)
33+ resid[1 ] = - 0.5 * u[1 ] + u[2 ] - du[1 ]
34+ resid[2 ] = u[1 ] - u[2 ] - du[2 ]
35+ end
36+ du0 = zeros (2 )
37+ differential_vars = [true , false ]
38+ dae_prob = DAEProblem (dae_f!, du0, [1.0 , 1.0 ], (0.0 , 1.0 ), differential_vars= differential_vars)
39+
40+ # Test all exported BDF solvers for allocation-free behavior
41+ # Standard ODE BDF methods
42+ bdf_solvers = [ABDF2 (), QNDF1 (), QBDF1 (), QNDF2 (), QBDF2 (), QNDF (), QBDF (), FBDF (), MEBDF2 ()]
43+
44+ # IMEX/Split methods need SplitODEProblem
45+ imex_solvers = [SBDF (order= 2 ), SBDF2 (), SBDF3 (), SBDF4 (), IMEXEuler (), IMEXEulerARK ()]
46+
47+ # DAE methods need DAEProblem
48+ dae_solvers = [DABDF2 (), DImplicitEuler (), DFBDF ()]
49+
50+ @testset " BDF Solver Allocation Analysis" begin
51+ for solver in bdf_solvers
52+ @testset " $(typeof (solver)) allocation check" begin
53+ integrator = init (prob, solver, dt= 0.1 , save_everystep= false , abstol= 1e-6 , reltol= 1e-6 )
54+ step! (integrator) # Setup step may allocate
55+
56+ # Use AllocCheck to verify step! is allocation-free
57+ allocs = check_allocs (step!, (typeof (integrator),))
58+
59+ # These solvers should be allocation-free, but mark as broken for now
60+ # to verify with AllocCheck (more accurate than @allocated)
61+ @test length (allocs) == 0 broken= true
62+
63+ if length (allocs) > 0
64+ println (" AllocCheck found $(length (allocs)) allocation sites in $(typeof (solver)) step!:" )
65+ for (i, alloc) in enumerate (allocs[1 : min (3 , end )]) # Show first 3
66+ println (" $i . $alloc " )
67+ end
68+ else
69+ println (" ✓ $(typeof (solver)) appears allocation-free with AllocCheck" )
70+ end
71+ end
72+ end
73+ end
74+
75+ @testset " IMEX Solver Allocation Analysis" begin
76+ for solver in imex_solvers
77+ @testset " $(typeof (solver)) allocation check" begin
78+ integrator = init (split_prob, solver, dt= 0.1 , save_everystep= false , abstol= 1e-6 , reltol= 1e-6 )
79+ step! (integrator) # Setup step may allocate
80+
81+ # Use AllocCheck to verify step! is allocation-free
82+ allocs = check_allocs (step!, (typeof (integrator),))
83+
84+ # These solvers should be allocation-free, but mark as broken for now
85+ # to verify with AllocCheck (more accurate than @allocated)
86+ @test length (allocs) == 0 broken= true
87+
88+ if length (allocs) > 0
89+ println (" AllocCheck found $(length (allocs)) allocation sites in $(typeof (solver)) step!:" )
90+ for (i, alloc) in enumerate (allocs[1 : min (3 , end )]) # Show first 3
91+ println (" $i . $alloc " )
92+ end
93+ else
94+ println (" ✓ $(typeof (solver)) appears allocation-free with AllocCheck" )
95+ end
96+ end
97+ end
98+ end
99+
100+ @testset " DAE Solver Allocation Analysis" begin
101+ for solver in dae_solvers
102+ @testset " $(typeof (solver)) allocation check" begin
103+ integrator = init (dae_prob, solver, dt= 0.1 , save_everystep= false , abstol= 1e-6 , reltol= 1e-6 )
104+ step! (integrator) # Setup step may allocate
105+
106+ # Use AllocCheck to verify step! is allocation-free
107+ allocs = check_allocs (step!, (typeof (integrator),))
108+
109+ # These solvers should be allocation-free, but mark as broken for now
110+ # to verify with AllocCheck (more accurate than @allocated)
111+ @test length (allocs) == 0 broken= true
112+
113+ if length (allocs) > 0
114+ println (" AllocCheck found $(length (allocs)) allocation sites in $(typeof (solver)) step!:" )
115+ for (i, alloc) in enumerate (allocs[1 : min (3 , end )]) # Show first 3
116+ println (" $i . $alloc " )
117+ end
118+ else
119+ println (" ✓ $(typeof (solver)) appears allocation-free with AllocCheck" )
120+ end
121+ end
122+ end
123+ end
124+ end
0 commit comments