You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Julia avoids specializing methods on arguments in certain cases, most notably when the argument type is <: Function and the function is not called in the function body, but only passed through to an inner function. This does not block type inference, only code generation, and runtime dispatch is often avoided by inlining since "pass-through" methods are usually small.
However, if a custom rule is written for such a method, Enzyme sees it as type unstable and invokes the runtime handler with its limited activity analysis. In addition to the performance penalty, this throws an error if activity analysis fails to prove that a keyword argument is Const. An important example is the custom rules for QuadGK.jl, since quadgk takes both a function argument and non-active float keyword arguments to set tolerances.
The solution could be for Enzyme to force recompilation with full specialization before choosing runtime vs. compile-time handling. This seems possible for a package like Enzyme, and would be fair game: I'm certain no one would object to this little bit of extra compilation in exchange for a faster and non-erroring gradient.
Reproducer below. Adding a type variable f::F to force specialization works around the issue.
using Enzyme
constcall(a, info) =call(() -> a; info)
functioncall(f; info=nothing) # errors# function call(f::F; info=nothing) where {F} # works@info"$info"# must use `info` somehow for the error to appearreturnf()
endfunction EnzymeRules.augmented_primal(
config, ::Const{typeof(call)}, ::Type{<:Active}, f::Active; kws...,
)
primal = EnzymeRules.needs_primal(config) ?call(f.val; kws...) :nothingreturn EnzymeRules.AugmentedReturn(primal, nothing, nothing)
endfunction EnzymeRules.reverse( # this rule is totally wrong, but that's beside the point
config, ::Const{typeof(call)}, ::Active, tape, f::Active; kws...,
)
return (f.val,)
end@showconstcall(1.0, 1e-10)
@showautodiff(Reverse, constcall, Active, Active(1.0), Const(1e-10))
(PS: This reproducer is somewhat deceptive in that call calls f in the body, so why is it still not specialized? My understanding is that the inner method is specialized, but not the keyword handling wrapper that is actually invoked by call(f; info).)
The text was updated successfully, but these errors were encountered:
Successor to #1845
Julia avoids specializing methods on arguments in certain cases, most notably when the argument type is
<: Function
and the function is not called in the function body, but only passed through to an inner function. This does not block type inference, only code generation, and runtime dispatch is often avoided by inlining since "pass-through" methods are usually small.However, if a custom rule is written for such a method, Enzyme sees it as type unstable and invokes the runtime handler with its limited activity analysis. In addition to the performance penalty, this throws an error if activity analysis fails to prove that a keyword argument is
Const
. An important example is the custom rules for QuadGK.jl, sincequadgk
takes both a function argument and non-active float keyword arguments to set tolerances.The solution could be for Enzyme to force recompilation with full specialization before choosing runtime vs. compile-time handling. This seems possible for a package like Enzyme, and would be fair game: I'm certain no one would object to this little bit of extra compilation in exchange for a faster and non-erroring gradient.
Reproducer below. Adding a type variable
f::F
to force specialization works around the issue.Output:
(PS: This reproducer is somewhat deceptive in that
call
callsf
in the body, so why is it still not specialized? My understanding is that the inner method is specialized, but not the keyword handling wrapper that is actually invoked bycall(f; info)
.)The text was updated successfully, but these errors were encountered: