Reputation: 1145
I am attempting to use the ForwardDiff.jl and / or ReverseDiff.jl libraries for computing the gradient in an optimization problem.
Both of these packages give me an error message related to ::getfield().
ReverseDiff gives me a LoadError:
MethodError: no method matching (::getfield(CalibrationModule, Symbol("#f#4"))
{AlgorithmParameters,ModelParameters,Guess,Array{Float64,1}})
(::ReverseDiff.TrackedArray{Float64,Float64,1,Array{Float64,1},Array{Float64,1}})
ForwardDiff gives me a LoadError:
MethodError: no method matching (::getfield(CalibrationModule, Symbol("#f#10"))
{AlgorithmParameters,ModelParameters,Guess,Array{Float64,1}})
(::Array{ForwardDiff.Dual{ForwardDiff.Tag{getfield(CalibrationModule,
Symbol("#f#10"))
{AlgorithmParameters,ModelParameters,Guess,Array{Float64,1}},Float64},Float64,6},1})
I have no idea how to make sense of this error message. My code is too complicated to post here, but as far as I can tell I am not using any libraries not written in Julia. I do extensively use custom data types (mutable structs) throughout, but I don't see why this would cause a problem...
Upvotes: 1
Views: 972
Reputation: 31362
Really hard to say without code, but:
A printout like (::getfield(CalibrationModule, Symbol(...)){...}(...)
is how Julia displays anonymous functions and closures. You're getting a method error that this anonymous function or closure doesn't support a signature that takes an Array
with either Dual
or Tracked
numbers. You probably have a function along the lines of:
function main()
...
f(A::Array{Float64}) = # ... some closure
...
f(...)
end
But the both ForwardDiff and ReverseDiff require running your program with dual or tracked numbers — which aren't Float64
. So you're getting a method error that your closure named f
doesn't accept arrays of these dual or tracked numbers.
Reduce the specificity of your f
closure to the widest thing it can support — likely something like f(A::AbstractArray{<:Number}) = ...
. Note that the two libraries do this slightly differently — ForwardDiff creates an array of Duals whereas ReverseDiff creates a tracked array of floating point numbers. Thus you want both ::AbstractArray
to support more than just Array
s (you should almost always do this unless you're calling C) and you want to loosen the element type to be any subtype of Number
. I'd recommend going even further and not care about the element type — you often don't need to care about it.
Upvotes: 2
Reputation: 548
From the Julia docs, the MethodError: no method matching
is thrown when there is no method with a matching type signature to the one you are calling. Julia has a dynamic type system but allows for type annotations that throw an exception if a value is not of the expected type. Since you are extensively using custom data types, it may be the case that you are passing in a value of custom data type to a method in ForwardDiff/ReverseDiff that expects a different type - hard to confirm without seeing the code but that's where I'd start looking.
Upvotes: 1