I’m using Enzyme to perform automatic differentiation.
I thought that as the primal code is type stable and non allocating, the enzyme autodiff function would also be. However for me the minimized example below gives the output:
Autodiff time
0.000005 seconds (4 allocations: 192 bytes)
It seems quite fragile. Moving things around, adding or removing @inline
or @noinline
sometimes changes the number of allocations, but in the full example of my code (not just this minimal example), I struggle to get rid of all of them.
using StaticArrays, Profile, PProf
using Enzyme: Reverse, autodiff, Active, Const, Duplicated
function mwe()
function func_to_be_differentiated(mat_vec::Vector, vec::Vector)
L = length(vec)
for i = 1:L
mat = mat_vec[i]
a = vec[i]
new_column = SVector(a, a, a)
for j = 1:3
mat[j, 1] = new_column[j]
end
mat[1, 1] = vec[i]
end
nothing
end
vec = zeros(3)
dvec = copy(vec)
matvec = [zeros(3, 1) for i in eachindex(vec)]
dmatvec = deepcopy(matvec)
function f(_matvec, vec)
func_to_be_differentiated(_matvec, vec)
_matvec[3][1, 1]
end
f(matvec, vec)
args = (Duplicated(matvec, dmatvec), Duplicated(vec, dvec))
println("Autodiff time")
@time autodiff(Reverse, f, args...)
# @profview test_autodiff(f, args; N=1000000)
end
mwe()
I’ve been looking at vscode @profview
, which attributes the allocations sometimes to getindex
or setindex
calls, sometimes to the first line of the loop for i = 1:L
, and I’ve been looking at pprof
of a Profile.Allocs.@profile sample_rate=1
profile, which I include but I don’t get whats going on.
I would upload the profile, but it is not a supported file type… alloc-profile.pb.gz