Skip to content

Commit 4b42841

Browse files
Cache Shooting ODE integrators by eltype
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
1 parent fa36d42 commit 4b42841

1 file changed

Lines changed: 30 additions & 5 deletions

File tree

lib/BoundaryValueDiffEqShooting/src/multiple_shooting.jl

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,23 @@ function SciMLBase.__solve(
4545

4646
internal_ode_kwargs = (; kwargs..., odesolve_kwargs..., save_end = true)
4747

48+
odecache_by_eltype = Dict{Tuple{Any, Int}, Any}()
4849
solve_internal_odes! = @closure (
4950
resid_nodes,
5051
us,
5152
p,
5253
cur_nshoot,
5354
nodes,
5455
odecache,
55-
) -> __multiple_shooting_solve_internal_odes!(
56-
resid_nodes, us, cur_nshoot, odecache, nodes, u0_size, N, ensemblealg, tspan
57-
)
56+
) -> begin
57+
odecache_ = __multiple_shooting_odecache_for_eltype(
58+
odecache, odecache_by_eltype, ensemblealg, prob, alg.ode_alg, us, cur_nshoot,
59+
u0_size, N, internal_ode_kwargs
60+
)
61+
__multiple_shooting_solve_internal_odes!(
62+
resid_nodes, us, cur_nshoot, odecache_, nodes, u0_size, N, ensemblealg, tspan
63+
)
64+
end
5865

5966
# This gets all the nshoots except the final SingleShooting case
6067
all_nshoots = __get_all_nshoots(alg.grid_coarsening, nshoots)
@@ -357,17 +364,35 @@ function __multiple_shooting_init_jacobian_odecache(
357364
)
358365
T_dual = eltype(overloaded_input_type(jac_cache))
359366
xduals = zeros(T_dual, size(u))
367+
prob = remake(prob; tspan = T_dual.(prob.tspan))
360368
return __multiple_shooting_init_odecache(
361369
ensemblealg, prob, alg, xduals, nshoots; kwargs...
362370
)
363371
end
364372

373+
function __multiple_shooting_odecache_for_eltype(
374+
odecache, odecache_by_eltype, ensemblealg, prob, ode_alg, us, nshoots, u0_size, N,
375+
internal_ode_kwargs
376+
)
377+
cache = odecache isa Vector ? first(odecache) : odecache
378+
eltype(cache.u) === eltype(us) && return odecache
379+
380+
key = (eltype(us), nshoots)
381+
return get!(odecache_by_eltype, key) do
382+
u0 = copy(reshape(@view(us[1:N]), u0_size))
383+
prob = remake(prob; tspan = eltype(us).(prob.tspan))
384+
__multiple_shooting_init_odecache(
385+
ensemblealg, prob, ode_alg, u0, nshoots; internal_ode_kwargs...
386+
)
387+
end
388+
end
389+
365390
# Not using `EnsembleProblem` since it is hard to initialize the cache and stuff
366391
function __multiple_shooting_solve_internal_odes!(
367392
resid_nodes, us, cur_nshoots::Int, odecache,
368393
nodes, u0_size, N::Int, ::EnsembleSerial, tspan
369394
)
370-
ts_ = Vector{Vector{typeof(first(tspan))}}(undef, cur_nshoots)
395+
ts_ = Vector{typeof(odecache.sol.t)}(undef, cur_nshoots)
371396
us_ = Vector{Vector{typeof(us)}}(undef, cur_nshoots)
372397

373398
for i in 1:cur_nshoots
@@ -389,7 +414,7 @@ function __multiple_shooting_solve_internal_odes!(
389414
resid_nodes, us, cur_nshoots::Int, odecache::Vector,
390415
nodes, u0_size, N::Int, ::EnsembleThreads, tspan
391416
)
392-
ts_ = Vector{Vector{typeof(first(tspan))}}(undef, cur_nshoots)
417+
ts_ = Vector{typeof(first(odecache).sol.t)}(undef, cur_nshoots)
393418
us_ = Vector{Vector{typeof(us)}}(undef, cur_nshoots)
394419

395420
n_splits = min(cur_nshoots, Threads.nthreads())

0 commit comments

Comments
 (0)