-
-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic mechanism for debugging/logging functions #3296
base: master
Are you sure you want to change the base?
Conversation
Try catch can be quite expensive though, how much of an overhead does this have? It can be okay for a debug mode though |
It actually seems free for an example that runs without errors, and better than the old behavior:
using ModelingToolkit, Plots, OrdinaryDiffEq, LinearAlgebra, BenchmarkTools
using ModelingToolkit: t_nounits as t, D_nounits as D
using Symbolics: scalarize
function Mass(; name, m = 1.0, xy = [0.0, 0.0], u = [0.0, 0.0])
ps = @parameters m = m
sts = @variables pos(t)[1:2]=xy v(t)[1:2]=u
eqs = scalarize(D.(pos) .~ v)
ODESystem(eqs, t, [pos..., v...], ps; name)
end
function Spring(; name, k = 1e4, l = 1.0)
ps = @parameters k=k l=l
@variables x(t), dir(t)[1:2]
ODESystem(Equation[], t, [x, dir...], ps; name)
end
function connect_spring(spring, a, b)
[spring.x ~ norm(scalarize(a .- b))
scalarize(spring.dir .~ scalarize(a .- b))]
end
function spring_force(spring)
-spring.k .* scalarize(spring.dir) .* (spring.x - spring.l) ./ spring.x
end
m = 1.0
xy = [1.0, -1.0]
k = 1e4
l = 1.0
center = [0.0, 0.0]
g = [0.0, -9.81]
@named mass = Mass(m = m, xy = xy)
@named spring = Spring(k = k, l = l)
eqs = [connect_spring(spring, mass.pos, center)
scalarize(D.(mass.v) .~ spring_force(spring) / mass.m .+ g)]
@named _model = ODESystem(eqs, t, [spring.x; spring.dir; mass.pos], [])
@named model = compose(_model, mass, spring)
sys = structural_simplify(model)
println("\nDebugging OFF, branch ", read(`git branch --show-current`, String))
prob = ODEProblem(sys, [], (0.0, 3.0))
bench = @benchmark solve(prob, Rosenbrock23())
display(bench)
println("\nDebugging ON, branch ", read(`git branch --show-current`, String))
dsys = debug_system(sys)
dprob = ODEProblem(dsys, [], (0.0, 3.0))
dbench = @benchmark solve(dprob, Rosenbrock23())
display(dbench)
git checkout --quiet master && julia bench.jl
git checkout --quiet generic_logged_functions && julia bench.jl
If you have a more complicated example in mind, I can try it. |
I added a short documentation page to help discover What do you think? |
b01cfdb
to
755b3b6
Compare
Format checker does not like this workaround to show errors in the documentation. Not sure if there is a better way to handle this :/ |
…ithout workarounds
I find
debug_system()
very helpful for seeing where code generated by symbolics crashes. But it currently only handles a limited set of error types. It also duplicates domain-checking logic that must be added for every function that is to be debugged, so I think it scales poorly.I propose this generic mechanism instead, which handles any error type, relies on the original functions' error/domain handling, and lets the user pass which functions they want debugged.
Checklist
contributor guidelines, in particular the SciML Style Guide and
COLPRAC.