EnzymeAD / Enzyme.jl

Julia bindings for the Enzyme automatic differentiator
https://enzyme.mit.edu
MIT License
428 stars 59 forks source link

Identify and attempt fix for gc bug #1386

Closed wsmoses closed 3 months ago

wsmoses commented 3 months ago

@vchuravy I need your help here making sure objects going through unsafe_to_pointer get permanently captured and not GC's in future [since we will use the constant for in future]

wsmoses commented 3 months ago

Obviously nondeterminstic reproducer (on 1.10)

wmoses@beast:~/git/Enzyme.jl (gcbg) $ cat csc.jl 
using Enzyme
using LinearAlgebra
using SparseArrays

Enzyme.API.printall!(true)
#--------------------------------------------------------------------------------
# Function to be differentiated
#--------------------------------------------------------------------------------
function eval(x::Vector{Float64})
    A = sparsevec([1, 1, 2, 3], [2.0*x[2]^3.0, 1.0-x[1], 2.0+x[3], -1.0])
    # B = sparsevec([1, 1, 2, 3], [2.0*x[2], 1.0-x[1], 2.0+x[3], -1.0])
    C = A + A #B
    return C[1]
end
#--------------------------------------------------------------------------------
# main
#--------------------------------------------------------------------------------
x = rand(Float64, 3)
dx = [0.0, 0.0, 0.0]

val = eval(x)

# compute gradient
#Enzyme.Compilerruntime_generic_augfwd(activity::Type{Val{1064}}, width::Val{1}, ModifiedBetween::Val{(true, true, true, true)}, RT::Val{@NamedTuple{1, 2, 3}}, f::typeof(sparsevec), df::Nothing, primal_1::Vector{Int64}, shadow_1_1::Nothing, primal_2::Vector{Float64}, shadow_2_1::Vector{Float64}, primal_3::typeof(+), shadow_3_1::Nothing)

autodiff(Reverse, eval, Duplicated(x, dx))
@show dx 

df_numeric = similar(x)
for i in eachindex(x)
    x_tmp = x[i]
    x_p = copy(x)
    x_p[i] += 1.0e-05
    x_m = copy(x)
    x_m[i] -= 1.0e-05
    df_numeric[i] = (eval(x_p) - eval(x_m)) / (2.0 * 1.0e-05)
end

display(df_numeric)

error = norm(dx-df_numeric)
println("error = $(error)")