How Enzyme handles Julia finalizers
mainWhen Enzyme performs automatic differentiation, it often needs to allocate 'shadow objects' (copies used to track derivatives). If the primal object has a Julia finalizer attached (used for resource management like manual memory allocation), Enzyme must handle it to prevent resource leaks.
Enzyme's approach is to attach the finalizer to the shadow object but define it to be 'inactive'—meaning the finalizer contains no instructions relevant to the AD process itself, but it still executes to ensure that resources associated with the shadow object are correctly released.
mutable struct Obj
x::Float64
function Obj(x)
o = new(x)
finalizer(o) do o
# resource management logic
end
return o
end
end
function f(x)
o = Obj(x)
return o.x
end
# Enzyme will manage the shadow object for 'o' and its finalizer
Enzyme.autodiff(Forward, f, Duplicated(1.0, 1.0))