You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
See the minimum example below, which loops until resulting in the shown crash.
I did some simple debugging (looking at the thread IDs) and found that PeriodicCallback seems to have a race issue with the index[] value getting reset (in the initialisation function) by different threads, leading to another thread trying to add a new tstop value in the wrong place (i.e. where tdir_tnew < integrator.t).
I can fix this issue by changing tnew = t0[] + (index[] + 1) * Δt (in PeriodicCallback function) to tnew = integrator.t + Δt -- however, I think the issue probably still remains in the condition function. So it probably needs a better thought out solution.
Could it be simply that EnsembleProblem is sharing callbacks between the threads, rather than making copies? I didn't look into this. [UPDATE: I did. See comments below. This particular error only occurs on OrbitalTrajectories v0.1.10.)
using OrbitalTrajectories
using DifferentialEquations
using Distributions
# Nominal initial spacecraft orbital state
system =CR3BP(:earth, :moon)
u0 = [0.7671053516112541, 0.0, 0.0, 0.0, 0.4859512921111289, 0.0]
state =State(system, u0, (0.0, 4.381287609345167))
# (OI) Orbit insertion errors
SD_OI = [1.2226878842036528e-6, 1.2226878842036528e-6, 3.303858750933275e-6, 8.512720156555774e-6, 1.0469667318982388e-5, 1.761252446183953e-5]
N_OI =Normal.(u0, SD_OI)
σ_OI =truncated.(N_OI, u0 -2*SD_OI, u0 +2*SD_OI)
# Function to generate a stochastic sample initial spacecraft stateprob_func(prob,i,repeat) =remake(prob; u0=rand.(σ_OI))
# Periodic callback that does nothing
Nt =10
dt = (state.tspan[end] - state.tspan[begin]) / Nt
callback =PeriodicCallback(integrator ->nothing, dt)
# Simulate a stochastic ensemble of orbits
ensemble_prob =EnsembleProblem(state; prob_func)
whiletrue# Loop until we crash due to race condition# NOTE: trajectories=1 does not lead to a crash. trajectories>1 does.
ensemble_orbits =solve(ensemble_prob, Vern7(), EnsembleThreads(); trajectories=2, callback)
end
Thinking through this a bit more, it does seem like it's more of an issue of not making copies of the callbacks when solving an EnsembleProblem. I've injected a simple deepcopy(callback) in my own __solve() dispatch (which passes down to the underlying __solve(ODEProblem)) and it seems to have solved this issue (NOTE: the above issue is therefore no longer present in OrbitalTrajectories >= 0.1.11).
I wonder if this should be default behaviour, or if there should be some way to trigger it automatically or otherwise warn very clearly that this can happen?
See the minimum example below, which loops until resulting in the shown crash.
I did some simple debugging (looking at the thread IDs) and found that
PeriodicCallback
seems to have a race issue with theindex[]
value getting reset (in the initialisation function) by different threads, leading to another thread trying to add a newtstop
value in the wrong place (i.e. wheretdir_tnew < integrator.t
).I can fix this issue by changing
tnew = t0[] + (index[] + 1) * Δt
(inPeriodicCallback
function) totnew = integrator.t + Δt
-- however, I think the issue probably still remains in thecondition
function. So it probably needs a better thought out solution.Could it be simply that
EnsembleProblem
is sharing callbacks between the threads, rather than making copies? I didn't look into this. [UPDATE: I did. See comments below. This particular error only occurs onOrbitalTrajectories v0.1.10
.)The text was updated successfully, but these errors were encountered: