-
Notifications
You must be signed in to change notification settings - Fork 2
Enzyme.jl: Unable to differentiate through Interpolator construction #75
Copy link
Copy link
Open
Description
Summary
Enzyme.jl cannot differentiate through Interpolator(points, values) construction in loss functions. This blocks a common use case of differentiating RBF interpolation w.r.t. input values.
Minimal Reproducible Example
using RadialBasisFunctions
using StaticArrays
import Enzyme
N = 30
points = [SVector{2}(rand(), rand()) for _ in 1:N]
values = sin.(getindex.(points, 1))
eval_points = [SVector{2}(rand(), rand()) for _ in 1:10]
function loss_interp(v)
interp = Interpolator(points, v)
result = interp(eval_points)
return sum(result .^ 2)
end
dv = zeros(N)
Enzyme.autodiff(Enzyme.Reverse, loss_interp, Enzyme.Active, Enzyme.Duplicated(values, dv))Error Messages
Without custom rules (HEAD of enzyme branch)
ERROR: IllegalTypeAnalysisException: Enzyme compilation failed due to illegal type analysis.
This usually indicates the use of a Union type, which is not fully supported...
Failure within method: MethodInstance for LinearAlgebra.var"#_factorize#135"(...)
The issue is that Interpolator internally calls factorize which returns a Union type (BunchKaufman or Diagonal).
Setting Enzyme.API.strictAliasing!(false) causes Julia to crash/segfault.
With custom EnzymeRules (attempted fix)
Adding custom augmented_primal and reverse rules for Interpolator construction leads to:
ERROR: AugmentedRuleReturnError: Incorrect return type for primal and shadow configuration...
expected : Interpolator{..., MB} where MB<:MonomialBasis
found : Interpolator{..., MonomialBasis{2, 2, ...}}
Enzyme requires exact type matching for custom rules, but the rule returns a concrete type while Julia's type inference produces an abstract type.
Root Causes
- LinearAlgebra.factorize Union return type: The
_factorizefunction can return eitherBunchKaufmanorDiagonal, which Enzyme cannot handle - Custom rule type matching: When defining custom rules to bypass the factorize issue, Enzyme's strict type matching requirements conflict with Julia's type inference
Environment
- Julia: 1.10.10 and 1.11.8
- Enzyme.jl: 0.13.129
- EnzymeCore.jl: 0.8.18
- RadialBasisFunctions.jl: 0.3.0 (enzyme branch)
Workaround
Currently, use ChainRules/Mooncake for Interpolator construction differentiation:
import DifferentiationInterface as DI
import Mooncake
backend = DI.AutoMooncake(; config=nothing)
grad = DI.gradient(loss_interp, backend, values)Related Issues
- Enzyme.jl #2699 (Julia 1.12+ compatibility)
Potential Fixes
- Add an Enzyme-compatible implementation of
Interpolatorthat avoidsfactorize(use explicit LU or Cholesky instead) - File an Enzyme.jl issue about relaxing type matching requirements for custom rules
- Rely on ChainRulesCore rrules which Enzyme can use on Julia < 1.12
🤖 Generated with Claude Code
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels