-
Notifications
You must be signed in to change notification settings - Fork 102
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
ForwardDiff.Dual recurses with logabsgamma #186
Comments
@simonbyrne any suggestions? |
I think the solution is to add the rules to https://github.com/JuliaDiff/DiffRules.jl/blob/a9b00c81ac0d103888b124b2b9f58a7c815cebf9/src/rules.jl#L67-L70. |
May I ask, how do you go about adding a diffrule for |
Seems like we need the following: using ForwardDiff: Dual, value, partials
import SpecialFunctions: logabsgamma
function logabsgamma(x::Dual{T}) where T
val, sgn = logabsgamma(value(x))
return (Dual{T}(val, partials(x) * DiffRules._abs_deriv(value(x)) * digamma(abs(value(x)))), )
end Is this something that should go into SpecialFunctions.jl? EDIT: The above together with adding in @define_diffrule SpecialFunctions.loggamma(x) =
:( SpecialFunctions.digamma($x) ) where @simonbyrne suggested, results in julia> ForwardDiff.derivative(z -> first(logabsgamma(z)), -1.0)
0.5772156649015315
julia> ForwardDiff.derivative(z -> first(logabsgamma(z)), 1.0)
-0.5772156649015315
julia> ForwardDiff.derivative(z -> loggamma(z), 1.0)
-0.5772156649015315 which seems good 👍 |
I believe @andreasnoack has already fixed this in DiffRules. |
Hah, didn't notice; great! But I don't believe that change fixes the EDIT: yeah I just tried with the updated master of DiffRules; |
From what I understand, it seems like either the above needs to be overloaded in ForwardDiff.jl, or SpecialFunctions.jl/src/gamma.jl Line 614 in 61f9058
needs to be removed? |
I think the underlying issue is this conversion combined with the fallback of |
I've only fixed While stack overflows are annoying I'm not sure that it's necessarily a bug. It's quite convenient to have a fallback definition that converts Reals with
I don't think that method is causing the recursion. I think it's the method right above. |
Technically it is of course always a specific method (eg |
Ah, sweet! Very much looking forward to getting these versions all bumped up.
I'm not too familiar with how DiffRules works, but seems to me that you can only define a rule for functions with a single return value which should be
Sorry, I meant as in the cause of the issue in this case. I definitively see the convience of this method. But the PR @tpapp has submitted to ForwardDiff seems like the way to go for fixing the issue of |
…ons v0.8 Zygote.jl already allows `[email protected]` but also suffers from the this issue: JuliaMath/SpecialFunctions.jl#186 (though different error message): ```julia julia> using Zygote, SpecialFunctions julia> Zygote.gradient(a -> SpecialFunctions.loggamma(a[1]), [1.0]) ERROR: TypeError: in _pullback, in ccall: first argument not a pointer or valid constant expression, expected Ptr, got Tuple{Symbol,String} Stacktrace: [1] logabsgamma at /var/home/tef30/.julia/packages/SpecialFunctions/ne2iw/src/gamma.jl:606 [inlined] [2] loggamma at /var/home/tef30/.julia/packages/SpecialFunctions/ne2iw/src/gamma.jl:650 [inlined] [3] FluxML#9 at ./REPL[9]:1 [inlined] [4] _pullback(::Zygote.Context, ::getfield(Main, Symbol("#FluxML#9#10")), ::Array{Float64,1}) at /var/home/tef30/.julia/packages/Zygote/8dVxG/src/compiler/interface2.jl:0 [5] _pullback(::Function, ::Array{Float64,1}) at /var/home/tef30/.julia/packages/Zygote/8dVxG/src/compiler/interface.jl:31 [6] pullback(::Function, ::Array{Float64,1}) at /var/home/tef30/.julia/packages/Zygote/8dVxG/src/compiler/interface.jl:37 [7] gradient(::Function, ::Array{Float64,1}) at /var/home/tef30/.julia/packages/Zygote/8dVxG/src/compiler/interface.jl:46 [8] top-level scope at none:0 ``` DiffRules recently got their version bumped to support SpecialFunctions v0.8 (JuliaDiff/DiffRules.jl@49129c0) which fixes this issue.
398: Relax bound for DiffRules to 0.1 for compat with SpecialFunctions v0.8 r=willtebbutt a=torfjelde Zygote.jl already allows `[email protected]` but also suffers from the this issue: JuliaMath/SpecialFunctions.jl#186 (though different error message): ```julia julia> using Zygote, SpecialFunctions julia> Zygote.gradient(a -> SpecialFunctions.loggamma(a[1]), [1.0]) ERROR: TypeError: in _pullback, in ccall: first argument not a pointer or valid constant expression, expected Ptr, got Tuple{Symbol,String} Stacktrace: [1] logabsgamma at /var/home/tef30/.julia/packages/SpecialFunctions/ne2iw/src/gamma.jl:606 [inlined] [2] loggamma at /var/home/tef30/.julia/packages/SpecialFunctions/ne2iw/src/gamma.jl:650 [inlined] [3] #9 at ./REPL[9]:1 [inlined] [4] _pullback(::Zygote.Context, ::getfield(Main, Symbol("##9#10")), ::Array{Float64,1}) at /var/home/tef30/.julia/packages/Zygote/8dVxG/src/compiler/interface2.jl:0 [5] _pullback(::Function, ::Array{Float64,1}) at /var/home/tef30/.julia/packages/Zygote/8dVxG/src/compiler/interface.jl:31 [6] pullback(::Function, ::Array{Float64,1}) at /var/home/tef30/.julia/packages/Zygote/8dVxG/src/compiler/interface.jl:37 [7] gradient(::Function, ::Array{Float64,1}) at /var/home/tef30/.julia/packages/Zygote/8dVxG/src/compiler/interface.jl:46 [8] top-level scope at none:0 ``` DiffRules recently got their version bumped to support SpecialFunctions v0.8 (JuliaDiff/DiffRules.jl@49129c0) which fixes this issue. EDIT: Together with `[email protected]`: ```julia julia> using Zygote, SpecialFunctions julia> Zygote.gradient(a -> SpecialFunctions.loggamma(a[1]), [1.0]) ([-0.577216],) ``` Co-authored-by: Tor Erlend Fjelde <[email protected]>
Was there any resolution to this issue? I'm encountering the same issue with |
Generally, the solution is to add derivative definitions to |
@andreasnoack Okay, so something like this needs to be added? @define_diffrule SpecialFunctions.besselkx(n, x) =
:(SpecialFunctions.besselkx($n, $x) - 1 / 2 * SpecialFunctions.besselkx($n - 1, $x) - 1 / 2 * SpecialFunctions.besselkx($n + 1, $x)) |
With SpecialFunctions 1.7.0 (or more concretely #347) the original example throws a MethodError instead of a StackOverflowError: julia> using ForwardDiff, SpecialFunctions
julia> d = ForwardDiff.Dual(3.5)
Dual{Nothing}(3.5)
julia> SpecialFunctions.logabsgamma(d)
ERROR: MethodError: no method matching _logabsgamma(::ForwardDiff.Dual{Nothing, Float64, 0})
Closest candidates are:
_logabsgamma(::Float64) at /home/david/.julia/packages/SpecialFunctions/5CocL/src/gamma.jl:601
_logabsgamma(::Float32) at /home/david/.julia/packages/SpecialFunctions/5CocL/src/gamma.jl:606
_logabsgamma(::Float16) at /home/david/.julia/packages/SpecialFunctions/5CocL/src/gamma.jl:611
...
Stacktrace:
[1] logabsgamma(x::ForwardDiff.Dual{Nothing, Float64, 0})
@ SpecialFunctions ~/.julia/packages/SpecialFunctions/5CocL/src/gamma.jl:599
[2] top-level scope
@ REPL[9]:1 |
I don't think there is more to do here. Any further action should happen in DiffRules. |
The text was updated successfully, but these errors were encountered: