Allow Duals and other types to pass through OptimizationFunction grad#1229
Conversation
| # internal buffers are concrete (e.g. `Float64`) and reject inputs of any other type. That is | ||
| # correct and fast for the optimization solve, but a downstream sensitivity layer (e.g. | ||
| # SciMLSensitivity's `OptimizationAdjoint`) differentiates the KKT stationarity conditions | ||
| # w.r.t. the parameters by pushing `ForwardDiff.Dual`s through the gradient: a dual `p` (and a |
There was a problem hiding this comment.
out of curiosity, why is p also Dual? The optimization parameters can be pretty much any arbitrary user given struct.
There was a problem hiding this comment.
The adjoint sensitivity finds the derivative of the solution of the optimization problem with respect to p. To find that we need:
where
The problem I'm having is the
because that's already a gradient with respect to
The optimization parameters can be pretty much any arbitrary user given struct.
Right, and if users want to get the sensitivity they'll either have to use types that are compatible with SciMLSensitivity or use SciMLStructures to tell SciMLSensitivity how to handle the user given struct. But that's already the case for ODEs and NonlinearSolves anyways, so it's still consistent with the rest of the ecosystem.
There was a problem hiding this comment.
To be clear I'm not sure this PR is a good idea, and it's incomplete anyway since I would also need the constraint jacobians to be able to take Duals.
But this or another workaround is what would be needed if we want to be able to reuse the stuff that optimization builds inside of the adjoint.
There was a problem hiding this comment.
ah, I see. It doesn't seem too invasive.
|
@SebastianM-C In order to support Enzyme for the optimization adjoint I needed to make some changes to the Enzyme extension. Mostly to allow the functions to accept other parameters, but there was also some boxing that Enzyme failed with, so I introduced some let blocks. There was also an issue where the closure was capturing a type value for the function annotation which Enzyme really did not like. So I changed it to precalculate so it would capture a Bool value instead. I don't think any of the changes are very intrusive but we definitely need to be careful with the Enzyme stuff, so if you see any issues let me know. |
0ff9b96 to
10ff293
Compare
a068fbc to
181f01e
Compare
|
@ChrisRackauckas @SebastianM-C In order for SciMLSensitivity to be able to reuse the closures built in Optimization, this PR has the changes needed. One, make it so that they all can accept a Two, make it so that they can accept Dual values. The way I do that in this PR is to use The changes in the Enzyme extension are to make sure that the closures can take a |
SebastianM-C
left a comment
There was a problem hiding this comment.
One, make it so that they all can accept a p.
Ah, nice, I wanted to have that anyway.
Checklist
contributor guidelines, in particular the SciML Style Guide and
COLPRAC.
Additional context
Essentially checks if the input types are different from the prep object. If they are, just reprep for that call.
Specifically allows sensitivity analysis to use ForwardDiff with
grad, to support SciML/SciMLSensitivity.jl#1444 .