# Continue a loop in Julia when the time out

When I use the DifferentialEquations.jl to solve a ODEs, some parameters set is time-consuming. I have write a loop to solve the ODEs at diverse parameters. I want to early terminate the time-consuming parameters set, for example more than 60 seconds and execute the next loop.

I don’t know how to realize this functions. Is there any the useful package?

eventlet package in Python is seems to work, but I know few about python. I want to know if any similar package in Julia.

2 Likes

Simplest solution maght be to use the maxiters flag in solve(... ;maxiters=1000, ...). If you realy need a more more accurate timing you can use a callback function:

using DiffEqBase, OrdinaryDiffEq

u0 = [1.,0.]
function fun(du,u,p,t)
du[2] = -u[1]
du[1] = u[2]
sleep(0.1)  # throttle the function
end
tspan = (0.0,10.0)
prob = ODEProblem(fun,u0,tspan)

struct Timer
tstart::Array{Float64,1}
runtime::Float64
Timer(t) = new([0.0],t)

end

function (timer::Timer)(u,t,integrator)
if timer.tstart[1] == 0.0
timer.tstart[1] = time()
end
time() - timer.tstart[1] >= timer.runtime && return true
end

affect!(integrator) = terminate!(integrator)
cb = DiscreteCallback(Timer(60),affect!)
sol = solve(prob,Tsit5(),callback=cb)


Thanks a lot
I found the diverse parameters often get different iteration times.
Besides, I found some parameter combinations really cause the solver too slow - it showed me Interrupted. Larger maxiters is needed. after a few hours, when i use the default maxiters flag. It also occupy too many memory. While, some parameter combinations may show me the solution a few seconds later. (both I used the AutoTsit5(Rosenbrock23()) solver).

I have noticed Base.Threads.@spawn could created a task of solve(...), and run in “backstage”. Then I can use timedwait(() -> istaskdone(tsk1), max_runtime) to timer the task. but I don’t know how to kill the task. Could you give me some advices?

using DifferentialEquations
u0 = [1.,0.]
function fun(du,u,p,t)
du[2] = -u[1]
du[1] = u[2]
sleep(0.1)  # throttle the function
end
tspan = (0.0,10.0)
prob = ODEProblem(fun,u0,tspan)

max_runtime = 10.0
tsk1 = Base.Threads.@spawn solve(prob, Tsit5())
timedwait(() -> istaskdone(tsk1), max_runtime)
sol = fetch(tsk1)
else
interrupt() # I don't know how to interrupt the task.
sol = nothing
end

see this post

...
sol = fetch(tsk1)
else
schedule(tsk1, ErrorException("stop"), error=true)
sol = nothing
end


will make your example work, but personally I would avoid such a hack

Thanks a lot
But it doesn’t seem to interrupt the task. The memory is still being used, and i almost could not do anything.

...
julia> run(free -h)
total        used        free      shared  buff/cache   available
Mem:           15Gi       2.3Gi        11Gi        42Mi       1.3Gi        12Gi
Swap:          15Gi       1.9Gi        14Gi
Process(free -h, ProcessExited(0))

julia> max_runtime = 10.0
10.0

julia> tsk1 = Base.Threads.@spawn solve(prob, Tsit5())

julia> timedwait(() -> istaskdone(tsk1), max_runtime)
:timed_out

sol = fetch(tsk1)
else
schedule(tsk1, ErrorException("stop"), error=true)
sol = nothing
end

julia> sleep(40)

julia> run(free -h)
total        used        free      shared  buff/cache   available
Mem:           15Gi       8.7Gi       5.4Gi        38Mi       1.3Gi       6.4Gi
Swap:          15Gi       1.9Gi        14Gi
Process(free -h, ProcessExited(0))


I have thought it is a basic function, such as ps, job, kill in SHELL.