FluxML / Zygote.jl

21st century AD
https://fluxml.ai/Zygote.jl/
Other
1.47k stars 209 forks source link

Compatibility with Rotations.jl #370

Open ferrolho opened 4 years ago

ferrolho commented 4 years ago

I have been trying to get Zygote to work along with RigidBodyDynamics.jl for computing Jacobians and Hessians of nonlinear functions. I have been trying to compute Jacobians using this function:

# Source: https://github.com/FluxML/Zygote.jl/issues/98#issuecomment-497739021
function zygote_jacobian(f, x)
    y = f(x)
    n = length(y)
    m = length(x)
    T = eltype(y)
    j = Array{T, 2}(undef, n, m)
    for i in 1:n
        j[i, :] .= gradient(x -> f(x)[i], x)[1]
    end
    return j
end

This method seems to be working for not-so-complicated functions. However, when I try to target functions using, e.g., Rotations.jl, I get the following error:

MethodError: no method matching (::getfield(Zygote, Symbol("##945#946")){Rotations.RotMatrix{3,Float64,9},StaticArrays.SArray{Tuple{3},Float64,1,3}})(::NamedTuple{(:data,),Tuple{Tuple{Float64,Nothing,Nothing}}})
Closest candidates are:
  #945(!Matched::AbstractArray{T,1} where T) at /home/henrique/.julia/packages/Zygote/bdE6T/src/lib/array.jl:207

Stacktrace:
 [1] (::getfield(Zygote, Symbol("##2365#back#947")){getfield(Zygote, Symbol("##945#946")){Rotations.RotMatrix{3,Float64,9},StaticArrays.SArray{Tuple{3},Float64,1,3}}})(::NamedTuple{(:data,),Tuple{Tuple{Float64,Nothing,Nothing}}}) at /home/henrique/.julia/packages/ZygoteRules/Jn4LO/src/adjoint.jl:48
 [2] * at /home/henrique/.julia/packages/RigidBodyDynamics/XgNGG/src/spatial/threevectors.jl:68 [inlined]
 [3] (::typeof(∂(*)))(::NamedTuple{(:v, :frame),Tuple{NamedTuple{(:data,),Tuple{Tuple{Float64,Nothing,Nothing}}},Nothing}}) at /home/henrique/.julia/packages/Zygote/bdE6T/src/compiler/interface2.jl:0
 [4] transform at /home/henrique/.julia/packages/RigidBodyDynamics/XgNGG/src/spatial/threevectors.jl:38 [inlined]
 [5] (::typeof(∂(transform)))(::NamedTuple{(:v, :frame),Tuple{NamedTuple{(:data,),Tuple{Tuple{Float64,Nothing,Nothing}}},Nothing}}) at /home/henrique/.julia/packages/Zygote/bdE6T/src/compiler/interface2.jl:0
 [6] forward_kinematics at ./In[11]:4 [inlined]
 [7] (::typeof(∂(forward_kinematics)))(::NamedTuple{(:data,),Tuple{Tuple{Float64,Nothing,Nothing}}}) at /home/henrique/.julia/packages/Zygote/bdE6T/src/compiler/interface2.jl:0
 [8] #3 at ./In[3]:8 [inlined]
 [9] (::typeof(∂(λ)))(::Float64) at /home/henrique/.julia/packages/Zygote/bdE6T/src/compiler/interface2.jl:0
 [10] (::getfield(Zygote, Symbol("##32#33")){typeof(∂(λ))})(::Float64) at /home/henrique/.julia/packages/Zygote/bdE6T/src/compiler/interface.jl:38
 [11] gradient(::Function, ::Array{Float64,1}) at /home/henrique/.julia/packages/Zygote/bdE6T/src/compiler/interface.jl:47
 [12] zygote_jacobian(::typeof(forward_kinematics), ::Array{Float64,1}) at ./In[3]:8
 [13] top-level scope at In[13]:1

Please confer this notebook for a full example that triggers the error shown above.

MikeInnes commented 4 years ago

Would be great if you can narrow this down to the specific function that's throwing an error. Looks like it's to do with Rotations.jl, so you might be able to reproduce just with that and none of the RigidBodyDynamics code. You can probably also get rid of the jacobian function and just use a gradient or pullback call (see here for more useful details).