-
-
Notifications
You must be signed in to change notification settings - Fork 235
[WIP] Simplify derivative_utils.jl
#876
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
Conversation
|
IMO one change we should make while doing this is that the W we want to calculate on should be passed in. See #872 for what happens when doing multithreaded implicit methods. That extra method should just be deleted when this is fixed. |
Codecov Report
@@ Coverage Diff @@
## master #876 +/- ##
==========================================
- Coverage 80.31% 80.27% -0.04%
==========================================
Files 92 92
Lines 30303 30322 +19
==========================================
+ Hits 24337 24341 +4
- Misses 5966 5981 +15
Continue to review full report at Codecov.
|
|
As soon as the algorithm-specific fields of the non-linear solvers are moved to the cache, there's no need anymore for separate |
| is_compos && (integrator.eigen_est = opnorm(J, Inf)) | ||
| end | ||
|
|
||
| function calc_J!(nlsolver::NLSolver, integrator, cache::OrdinaryDiffEqConstantCache, is_compos) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There already exists an implementation for out-of-place function, it's called calc_J. So if we need an in-place variant calc_J! (which I'm not sure about) we could just define calc_J! as cache.J = calc_J(...)
src/derivative_utils.jl
Outdated
| if DiffEqBase.has_jac(f) | ||
| nlsolver.cache.J = f.jac(uprev, p, t) | ||
| else | ||
| nlsolver.cache.J = jacobian(nlsolver.uf,uprev,integrator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should update uf first, similar to the other implementations of calc_J!. This is currently missing in the out-of-place implementations calc_J.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why does calc_J produce the right answer without updating uf ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's updated in calc_W! in lines such as https://github.com/JuliaDiffEq/OrdinaryDiffEq.jl/blob/dcff0bd6809adc640ce910ddbeeba8ed05091431/src/derivative_utils.jl#L525 (but not for p, so that's still not correct). I think we should remove those updates in calc_W! since the update should only happen if we actually need uf, which is only the case in calc_J.
| is_compos && (integrator.eigen_est = opnorm(J, Inf)) | ||
| end | ||
|
|
||
| function calc_J_in_cache!(integrator, cache::OrdinaryDiffEqConstantCache, is_compos) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I said, I'm not sure we want to do this.
| J = f.jac(uprev, p, t) | ||
| else | ||
| cache.uf.t = t | ||
| cache.uf.p = p |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! 👍 Can you remove the updates of uf in the oop version of calc_W!?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking of delete oop version of cache_W! directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And only use update_W!? Currently I don't like that calc_W! is called calc_W! both for in-place and out-of-place functions but updates W only for the in-place functions and returns a new W for the out-of-place functions. So I thought maybe it could be done similar to calc_J and calc_J!, i.e., we could have an out-of-place variant calc_W and an updating variant calc_W!.
Moreover, I'm not happy with the fact that at the moment there's a lot of reuse strategies hidden in the implementation of calc_W!. Maybe it would be cleaner if calc_W! would just calculate W, without considering any reuse strategies, similar to what we do in calc_J. Ideally then we would have a separate function (such as update_W!) that first figures out if J should be updated (and then calls calc_J!) and then if W should be updated (and then calls calc_W!).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree.
|
I'm a bit confused by the |
|
It was one implementation in the beginning and then just copied to a new function when the non-linear solvers were changed. I'm sure many parts can be improved. |
|
Why is |
|
Check out #878 if that helps us out for this patch |
|
and this intersects with SciML/DiffEqBase.jl#325 . @devmotion might want to take note of all of these and make sure that works with these 3 planned changes. |
|
The non-linear solver changes will break the accesses |
|
OK, let's merge this and continue improving derivative_utils.jl in separate PRs. |
Continuing from #873 and #871 . The goal is to simplify four
calc_W!functions into two groups: one for rosenbrock, one for nlnewton.calc_W!should behave the same for OOP and IIP.