So to put the original question shorter and more precise: is it possible to share parameters for an ensemble problem?
For example,
using DifferentialEquations
function lorenz!(du,u,p,t)
σ,ρ,β = p
du[1] = σ*(u[2]-u[1])
du[2] = u[1]*(ρ-u[3]) - u[2]
du[3] = u[1]*u[2] - β*u[3]
end
"Initial state perturbation for EnsembleProblem."
function prob_func(prob, i, repeat)
prob.u0[1] += i
prob
end
u0 = [1.0,0.0,0.0]
p_tuple = (10,28,8/3)
#p_vector = Any[10,28, 8/3]
tspan = (0.0,100.0)
prob = ODEProblem(lorenz!,u0,tspan,p_tuple)
#sol = solve(prob, Tsit5())
ensemble_prob = EnsembleProblem(prob; prob_func)
trajectories = 1
@time sols = solve(ensemble_prob, Tsit5(), EnsembleThreads(); trajectories,
save_on=false, save_start=false, save_end=false,);
In this case, the parameter p = p_tuple = (10,28,8/3)
is not shared: each trajectory will generate a copy. This may not be a problem for a parameter with 3 scalars, but in my original problem, two of the parameters are arrays, and I cannot afford to copy field arrays for each trajectory.
I guess if I use a vector type for the parameter, p = Any[10, 28, 8/3]
, then probably the parameters are referring to the same memory? Even this is true, there is another warning from DifferentialEquations
┌ Warning: Using arrays or dicts to store parameters of different types can hurt performance.
│ Consider using tuples instead.
└ @ SciMLBase C:\Users\hyzho\.julia\packages\SciMLBase\ZUwcW\src\performance_warnings.jl:32
I added Any
on purpose, because in my original problem, param is of type
Tuple{Float64, Float64, TestParticle.Field{false, TestParticle.var"#get_field#3"{Interpolations.ScaledInterpolation{Float64, 3, Interpolations.FilledExtrapolation{Float64, 3, Interpolations.BSplineInterpolation{Float64, 3, Array{Float64, 3}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Float64}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}, Interpolations.ScaledInterpolation{Float64, 3, Interpolations.FilledExtrapolation{Float64, 3, Interpolations.BSplineInterpolation{Float64, 3, Array{Float64, 3}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Float64}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}, Interpolations.ScaledInterpolation{Float64, 3, Interpolations.FilledExtrapolation{Float64, 3, Interpolations.BSplineInterpolation{Float64, 3, Array{Float64, 3}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Float64}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}}}, TestParticle.Field{false, TestParticle.var"#get_field#3"{Interpolations.ScaledInterpolation{Float64, 3, Interpolations.FilledExtrapolation{Float64, 3, Interpolations.BSplineInterpolation{Float64, 3, Array{Float64, 3}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Float64}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}, Interpolations.ScaledInterpolation{Float64, 3, Interpolations.FilledExtrapolation{Float64, 3, Interpolations.BSplineInterpolation{Float64, 3, Array{Float64, 3}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Float64}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}, Interpolations.ScaledInterpolation{Float64, 3, Interpolations.FilledExtrapolation{Float64, 3, Interpolations.BSplineInterpolation{Float64, 3, Array{Float64, 3}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Float64}, Interpolations.BSpline{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}}}}
and when I tried to convert that into an vector via collect(param)
, Julia gave up in type inference.
I got stuck here.