-
Notifications
You must be signed in to change notification settings - Fork 146
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
WIP: Refactor ForwardDiff to utilize NDuals and replace API #27
Conversation
julia 0.3- | ||
DualNumbers | ||
julia 0.4- | ||
NDuals |
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 think it makes sense just to move over the NDuals
code.
Cool stuff! Could you update some of the tests so that we can get a feel for what the new API looks like? |
Also this won't pass on travis with a dependency on NDuals. |
Both of these sound like good next steps to me! |
-(h::HessianNum) = HessianNum(-grad(h), -hess(h)) | ||
|
||
const h_univar_funcs = Tuple{Symbol, Expr}[ | ||
(:sqrt, :((-grad(h,i)*grad(h,j)+2*value(h)*hess(h,i)) / (4*(value(h)^(1.5))))), |
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.
Could you document the format for this expression table? It's not really clear to me what's going on
2bc8b5a
to
cea22d8
Compare
It seems that the tests are erroring on Travis due to a noisy Calculus.jl deprecation warning. The cause of this warning was recently fixed on Calculus.jl's master branch (in this commit). Locally, I'm running off of Calculus.jl's master branch, and can confirm all the tests pass on my machine. What's the right path forward? Perhap's there a flag to suppress the deprecation warnings that we could turn on just for testing? |
I'll just tag Calculus. |
This is awesome work. Do you need any help on coveralls support? |
@felipenoris Thanks! I just added a line to the Travis file to submit the coverage report to Coveralls, but Coveralls doesn't seem to be updating the repo page here (I can't see other branches besides master, which is also strange). |
It seems that you got some error on Coveralls.process_folder():
I´m not sure that this is the cause, but you can test it by running this on your own machine:
I would be glad to test this for you when I get home tonight. |
That looks like it might be JuliaLang/JuliaParser.jl#19, the same thing that's holding up base coverage numbers. The approaches there are either find workaround alternate syntax that JuliaParser is happy with, help fix JuliaParser, or bug Jake until he does it. |
@tkelman is right. It's the same error as JuliaCI/Coverage.jl#77. |
@tkelman @felipenoris Thanks for pointing out the source of the issue! I'm going to see whether I can cook up a fix myself today for the |
Looks like you're close to a merge. Awesome! |
I'm sorry. I see that this was discussed elsewhere. |
Yeah, I'm in favor of not exporting |
@mlubin I think I'm with you there. Users can always alias it to another name if they wish, but just popping the function into the global namespace could easily cause issues for whoever accidentally calls the Calculus.jl version without realizing it. How should we go about dealing with the other functions ( |
Extending a function in Base is asserting global ownership of a particular signature, but I don't think it's an issue to export methods which don't conflict (currently) with Base. |
Sounds good. |
end | ||
end | ||
|
||
@generated function grad_workvec{N,T}(::Type{Dim{N}}, ::Type{T}) |
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.
Are you planning on restructuring this? The memory leak is a real issue
I created an From here, we could either: a) Merge or b) Merge |
You could open up a pull request to merge |
I apologize in advance for asking questions in a WIP PR but I figured this was the best place since it seems to likely soon be the new It could possible be done with an extra |
Opinions on where the API should go are definitely welcome!
@mlubin What do you think of this? The downside is that I would really like to keep the API as simple as possible, and the more arguments we have to support the complicated things can become... The other argument against this is that, in most cases, the cost of calling the target function on it's own will probably be amortized in the cost of evaluating higher order derivatives anyway, so that it might not really hurt you that much performance-wise to call it twice. OTOH, if the target function is really costly to evaluate, I suppose it's frustrating to see that work get thrown away rather than reused. If we do decide support this, it'd only make sense if we support the retrieval of all lower order derivative results (e.g. if you take the Either way, I don't think working to support this should be a block for merging this PR. We could merge this PR and extend the API later without breakage to support this. |
I agree that having an API as simple as the one in this PR is a great strength and significant thought should go into any additions of, for example, function arguments as to not clutter the API. My application that I am playing around using I believe that it is quite common to both want the function value and the derivative so even if the derivative part takes the majority of the time it could be argued that (if we figure out some clean way to do it), being able to get them both in just one function call could be argued being good API practice. I will think a bit and see if I can get any good, clean ways this could be done. |
lol, I know what you mean. I do think this would work with a keyword argument in place to specify "don't load my results into an array before giving them to me, instead just give me the resulting Also, if you want to figure out what an implementation might look like, note that the most up-to-date API implementation is currently here, which we plan on merging in to this PR once it's been approved, then finally merging this PR back to master. |
There's definitely an argument to be made for returning the lower derivatives or function values if available, but that's out of scope for this PR. We should continue the discussion in an issue after this PR merges and things stabilize a bit. |
Allow chunk-sizing options, and a more robust caching layer to fix leaky generated functions
💯 |
Awesome! Thank you! |
Great to see this merged. |
Please don't forget to bump the minor version (or major if this were post-1.0) for the first metadata tag that includes this rewrite. |
Definitely |
This PR does a lot of stuff...likely way more than should fit in one PR, but I got a bit carried away with my refactor.
Changes
matrix_fad
,powerseries_fad
, anddual_fad
folders, and moved the contents oftyped_fad
tosrc
.matrix_fad
,powerseries_fad
) are gone, the API can be simplified, so I took a crack at it. I'll be working on documentation soon, but the exported functions list and fad_api.jl contain the relevant code necessary to understand my attempt.Notably, it makes more use of my "generated function closure caching trick (TM)" in order to speed up/reuse memory when repeatedly using the same NDuals type to take the gradient/Hessian/etc. This technique has the potential to dangerously behave like a memory leak in a specific edge case (read the code comments), but I can't imagine a user ever reaching that case in a real world situation.It also supports a caching layer for re-usage of work arrays (documented in the README).FAD*
types to*Number
(e.g.FADHessian
-->HessianNumber
).RefactorsPorts in the work from NDuals.jl as a new type,FADHessian
andFADTensor
to utilize NDuals.jl, thereby allowing the removal ofGraDual
and dependence on DualNumbers.jl.GradientNumber
.GradientNum
and downstream types.FADHessian.jlHessianNum.jl andFADTensor.jlTensorNum.jl:GradientNumber
,HessianNumber
, andTensorNumber
types under a new supertype,ForwardDiffNumber <: Number
..
-based accesses that plagued the old implementation with consistent calls to proper accessor methods .Still in progress
F<:ForwardDiffNumber
typesGradientNumber
HessianNumber
TensorNumber