EnzymeAD / Enzyme.jl

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

Basic SparseMatrixCSC calculations do not work. #1381

Open ToPo-ToPo-ToPo opened 8 months ago

ToPo-ToPo-ToPo commented 8 months ago

I would like to use the basic calculations in SparseMatrixCSC, but they do not work. The following is a simple SparseMatrixCSC-to-SparseMatrixCSC addition program.

using Enzyme
using LinearAlgebra
using SparseArrays
#--------------------------------------------------------------------------------
# Function to be differentiated
#--------------------------------------------------------------------------------
function eval(x::Vector{Float64})
    A = sparse([1, 1, 2, 3], [1, 3, 2, 3], [2.0*x[2]^3.0, 1.0-x[1], 2.0+x[3], -1.0])
    B = sparse([1, 1, 2, 3], [1, 3, 2, 3], [2.0*x[2], 1.0-x[1], 2.0+x[3], -1.0])
    C = A + B
    return C[1, 1] + C[2, 2]
end
#--------------------------------------------------------------------------------
# main
#--------------------------------------------------------------------------------
x = rand(Float64, 3)
dx = [0.0, 0.0, 0.0]

val = eval(x)

# compute gradient
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)")

The errors that occur when executing the program are as follows:

ERROR: BoundsError: attempt to access 4-element Vector{Int64} at index [0]
Stacktrace:
  [1] _deleteend!
    @ ./array.jl:1081 [inlined]
  [2] resize!
    @ ./array.jl:1320 [inlined]
  [3] trimstorage!
    @ ~/.julia/juliaup/julia-1.10.2+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:135
  [4] _map_zeropres!
    @ ~/.julia/juliaup/julia-1.10.2+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:361
  [5] _noshapecheck_map
    @ ~/.julia/juliaup/julia-1.10.2+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:184
  [6] map
    @ ~/.julia/juliaup/julia-1.10.2+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:1187 [inlined]
  [7] +
    @ ~/.julia/juliaup/julia-1.10.2+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/sparsematrix.jl:2242 [inlined]
  [8] eval
    @ ~/my_program/GitHub/JuliaOptOS/tests/Enzyme/sparse_array_tests/basic_add.jl:11 [inlined]
  [9] diffejulia_eval_2011wrap
    @ ~/my_program/GitHub/JuliaOptOS/tests/Enzyme/sparse_array_tests/basic_add.jl:0
 [10] macro expansion
    @ ~/.julia/packages/Enzyme/l4FS0/src/compiler.jl:5378 [inlined]
 [11] enzyme_call
    @ ~/.julia/packages/Enzyme/l4FS0/src/compiler.jl:5056 [inlined]
 [12] CombinedAdjointThunk
    @ ~/.julia/packages/Enzyme/l4FS0/src/compiler.jl:4998 [inlined]
 [13] autodiff
    @ ~/.julia/packages/Enzyme/l4FS0/src/Enzyme.jl:215 [inlined]
 [14] autodiff
    @ ~/.julia/packages/Enzyme/l4FS0/src/Enzyme.jl:238 [inlined]
 [15] autodiff(mode::ReverseMode{false, FFIABI}, f::typeof(eval), args::Duplicated{Vector{Float64}})
    @ Enzyme ~/.julia/packages/Enzyme/l4FS0/src/Enzyme.jl:224
 [16] top-level scope
    @ ~/my_program/GitHub/JuliaOptOS/tests/Enzyme/sparse_array_tests/basic_add.jl:23
wsmoses commented 7 months ago

Should now be fixed on main

ToPo-ToPo-ToPo commented 6 months ago

I have been told that this has been supported, but in my environment, the following error occurred and the calculation could not be performed. Enzyme.jl: Enzyme v0.12.7

┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/kqxyC/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/kqxyC/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/kqxyC/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/kqxyC/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/kqxyC/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/kqxyC/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/kqxyC/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/kqxyC/src/utils.jl:59
ERROR: BoundsError: attempt to access 4-element Vector{Int64} at index [0]
Stacktrace:
  [1] _deleteend!
    @ ./array.jl:1081 [inlined]
  [2] resize!
    @ ./array.jl:1320 [inlined]
  [3] trimstorage!
    @ ~/.julia/juliaup/julia-1.10.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:135
  [4] _map_zeropres!
    @ ~/.julia/juliaup/julia-1.10.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:361
  [5] _noshapecheck_map
    @ ~/.julia/juliaup/julia-1.10.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:184
  [6] map
    @ ~/.julia/juliaup/julia-1.10.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:1187 [inlined]
  [7] +
    @ ~/.julia/juliaup/julia-1.10.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/sparsematrix.jl:2242 [inlined]
  [8] eval
    @ ~/my_program/GitHub/JuliaOptOS/tests/Enzyme/sparse_array_tests/basic_add.jl:11 [inlined]
  [9] diffejulia_eval_6074wrap
    @ ~/my_program/GitHub/JuliaOptOS/tests/Enzyme/sparse_array_tests/basic_add.jl:0
 [10] macro expansion
    @ ~/.julia/packages/Enzyme/UKzrf/src/compiler.jl:5787 [inlined]
 [11] enzyme_call
    @ ~/.julia/packages/Enzyme/UKzrf/src/compiler.jl:5453 [inlined]
 [12] CombinedAdjointThunk
    @ ~/.julia/packages/Enzyme/UKzrf/src/compiler.jl:5332 [inlined]
 [13] autodiff
    @ ~/.julia/packages/Enzyme/UKzrf/src/Enzyme.jl:291 [inlined]
 [14] autodiff
    @ ~/.julia/packages/Enzyme/UKzrf/src/Enzyme.jl:315 [inlined]
 [15] autodiff(mode::ReverseMode{false, FFIABI, false}, f::typeof(eval), args::Duplicated{Vector{Float64}})
    @ Enzyme ~/.julia/packages/Enzyme/UKzrf/src/Enzyme.jl:300
 [16] top-level scope
    @ ~/my_program/GitHub/JuliaOptOS/tests/Enzyme/sparse_array_tests/basic_add.jl:23
wsmoses commented 6 months ago

@ToPo-ToPo-ToPo what is your version of Julia / OS.

The code above works for me on Enzyme#main

wsmoses commented 6 months ago

Also please show the package environments as well

ToPo-ToPo-ToPo commented 6 months ago

I use 1.10.3+0.aarch64.apple.darwin14 (release). The packages used are as follows:

Status `~/.julia/environments/v1.10/Project.toml`
  [6e4b80f9] BenchmarkTools v1.5.0
  [082447d4] ChainRules v1.66.0
  [d360d2e6] ChainRulesCore v1.23.0
  [7da242da] Enzyme v0.12.7
  [95c220a8] ExtendableSparse v1.4.0
  [f6369f11] ForwardDiff v0.10.36
  [42fd0dbc] IterativeSolvers v0.9.4
  [ba0b0d4f] Krylov v0.9.6
  [7ed4a6bd] LinearSolve v2.30.0
  [76087f3c] NLopt v1.0.2
  [b8a86587] NearestNeighbors v0.4.16
  [91a5bcdd] Plots v1.40.4
  [37e2e3b7] ReverseDiff v1.15.3
  [e56a9233] Sparspak v0.3.9
  [64499a7a] WriteVTK v1.19.1
  [e88e6eb3] Zygote v0.6.70
wsmoses commented 6 months ago

Just to double check, since I'm having difficulty reproducing: what happens if you're in an enviroment with only Enzyme.

ToPo-ToPo-ToPo commented 6 months ago

All packages were removed, leaving only Enzyme.jl available. When the same program was run, the error was not resolved.

Enzyme.jl: Enzyme v0.12.8

┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/nWT2N/src/utils.jl:59
ERROR: BoundsError: attempt to access 4-element Vector{Int64} at index [0]
Stacktrace:
  [1] _deleteend!
    @ ./array.jl:1081 [inlined]
  [2] resize!
    @ ./array.jl:1320 [inlined]
  [3] trimstorage!
    @ ~/.julia/juliaup/julia-1.10.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:135
  [4] _map_zeropres!
    @ ~/.julia/juliaup/julia-1.10.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:361
  [5] _noshapecheck_map
    @ ~/.julia/juliaup/julia-1.10.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:184
  [6] map
    @ ~/.julia/juliaup/julia-1.10.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:1187 [inlined]
  [7] +
    @ ~/.julia/juliaup/julia-1.10.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/sparsematrix.jl:2242 [inlined]
  [8] eval
    @ ~/my_program/GitHub/JuliaOptOS/tests/Enzyme/sparse_array_tests/basic_add.jl:11 [inlined]
  [9] diffejulia_eval_2098wrap
    @ ~/my_program/GitHub/JuliaOptOS/tests/Enzyme/sparse_array_tests/basic_add.jl:0
 [10] macro expansion
    @ ~/.julia/packages/Enzyme/UZsMX/src/compiler.jl:5855 [inlined]
 [11] enzyme_call
    @ ~/.julia/packages/Enzyme/UZsMX/src/compiler.jl:5521 [inlined]
 [12] CombinedAdjointThunk
    @ ~/.julia/packages/Enzyme/UZsMX/src/compiler.jl:5400 [inlined]
 [13] autodiff
    @ ~/.julia/packages/Enzyme/UZsMX/src/Enzyme.jl:291 [inlined]
 [14] autodiff
    @ ~/.julia/packages/Enzyme/UZsMX/src/Enzyme.jl:315 [inlined]
 [15] autodiff(mode::ReverseMode{false, FFIABI, false}, f::typeof(eval), args::Duplicated{Vector{Float64}})
    @ Enzyme ~/.julia/packages/Enzyme/UZsMX/src/Enzyme.jl:300
 [16] top-level scope
    @ ~/my_program/GitHub/JuliaOptOS/tests/Enzyme/sparse_array_tests/basic_add.jl:23
wsmoses commented 6 months ago

I tried it out on an arm macbook and it still worked for me:

julia> versioninfo()
Julia Version 1.10.2
Commit bd47eca2c8a (2024-03-01 10:14 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin22.4.0)
  CPU: 10 × Apple M1 Max
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, apple-m1)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)

I'm not really sure how to help more here since I can't reproduce, if you have any ideas.

Perhaps hop on a call or something

ToPo-ToPo-ToPo commented 6 months ago

My environment is as follows. I tried the same version of julia as you, but the error was not resolved. I don't know what is wrong.

julia> versioninfo()
Julia Version 1.10.2
Commit bd47eca2c8a (2024-03-01 10:14 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin22.4.0)
  CPU: 8 × Apple M2
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, apple-m1)
Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores)
wsmoses commented 2 months ago

What if you try Julia 1.10.5?

wsmoses commented 2 months ago

going to close for now as cannot reproduce, please reopen if it persists

hochunlin commented 2 months ago

I had the same issue on my side when I tried to do a simple SparseMatrixCSC-to-SparseMatrixCSC addition and used the Enzyme to do autodiff.

If I ran the script posted by @ToPo-ToPo-ToPo, I got the following error message,

ERROR: BoundsError: attempt to access 4-element Vector{Int64} at index [0]
Stacktrace:
  [1] _growend!
    @ ./array.jl:1072 [inlined]
  [2] resize!
    @ ./array.jl:1315 [inlined]
  [3] _allocres
    @ ~/.julia/juliaup/julia-1.10.5+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:254 [inlined]
  [4] _noshapecheck_map
    @ ~/.julia/juliaup/julia-1.10.5+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:183
  [5] map
    @ ~/.julia/juliaup/julia-1.10.5+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/higherorderfns.jl:1187 [inlined]
  [6] +
    @ ~/.julia/juliaup/julia-1.10.5+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/sparsematrix.jl:2242 [inlined]
  [7] eval
    @ ~/repos/Enzyme_latest/Enzyme.jl/test/issue_example.jl:10 [inlined]
  [8] diffejulia_eval_2112wrap
    @ ~/repos/Enzyme_latest/Enzyme.jl/test/issue_example.jl:0
  [9] macro expansion
    @ ~/repos/Enzyme_latest/Enzyme.jl/src/compiler.jl:8839 [inlined]
 [10] enzyme_call
    @ ~/repos/Enzyme_latest/Enzyme.jl/src/compiler.jl:8405 [inlined]
 [11] CombinedAdjointThunk
    @ ~/repos/Enzyme_latest/Enzyme.jl/src/compiler.jl:8178 [inlined]
 [12] autodiff
    @ ~/repos/Enzyme_latest/Enzyme.jl/src/Enzyme.jl:491 [inlined]
 [13] autodiff
    @ ~/repos/Enzyme_latest/Enzyme.jl/src/Enzyme.jl:537 [inlined]
 [14] autodiff(mode::ReverseMode{false, false, FFIABI, false, false}, f::typeof(eval), args::Duplicated{Vector{Float64}})
    @ Enzyme ~/repos/Enzyme_latest/Enzyme.jl/src/Enzyme.jl:504
 [15] top-level scope
    @ ~/repos/Enzyme_latest/Enzyme.jl/test/issue_example.jl:22

I am in an environment with only Enzyme (v0.13.7) and the following is my environment:

(Enzyme) pkg> status Enzyme 
Project Enzyme v0.13.7

julia> versioninfo()
Julia Version 1.10.5
Commit 6f3fdf7b362 (2024-08-27 14:19 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin22.4.0)
  CPU: 12 × Apple M3 Pro
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, apple-m1)
Threads: 1 default, 0 interactive, 1 GC (on 6 virtual cores)
Environment:
  JULIA_PKG_USE_CLI_GIT = true
  JULIA_EDITOR = code
  JULIA_NUM_THREADS =

@wsmoses Could you look at this issue again or give me any suggestion to debug it?