Enzyme.jl icon indicating copy to clipboard operation
Enzyme.jl copied to clipboard

Enzyme Mutability Error with reverse mode

Open mhauru opened this issue 11 months ago • 6 comments

MWE

module MWE

using Enzyme: Enzyme

function _logpdf(x)
    s = sum(i for (i, xi) in enumerate(x))
    return s
end

function f(x)
    v = eachrow(x)
    return sum(_logpdf, v)
end

x = reshape([0.8, 0.3, 0.2, 0.7], (2, 2))
@show f(x)
Enzyme.gradient(Enzyme.Reverse, f, x)

end

Output:

f(x) = 6
ERROR: Enzyme Mutability Error: Cannot add one in place to immutable value 6
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] add_one_in_place(x::Int64)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/R6sE8/src/compiler.jl:4870
  [3] augmented_julia_f_4784wrap
    @ ./REPL[14]:0
  [4] macro expansion
    @ ~/.julia/packages/Enzyme/R6sE8/src/compiler.jl:5340 [inlined]
  [5] enzyme_call
    @ ~/.julia/packages/Enzyme/R6sE8/src/compiler.jl:4878 [inlined]
  [6] AugmentedForwardThunk
    @ ~/.julia/packages/Enzyme/R6sE8/src/compiler.jl:4814 [inlined]
  [7] autodiff
    @ ~/.julia/packages/Enzyme/R6sE8/src/Enzyme.jl:396 [inlined]
  [8] autodiff
    @ ~/.julia/packages/Enzyme/R6sE8/src/Enzyme.jl:524 [inlined]
  [9] macro expansion
    @ ~/.julia/packages/Enzyme/R6sE8/src/sugar.jl:324 [inlined]
 [10] gradient(::EnzymeCore.ReverseMode{false, false, EnzymeCore.FFIABI, false, false}, ::typeof(Main.MWE.f), ::Matrix{Float64})
    @ Enzyme ~/.julia/packages/Enzyme/R6sE8/src/sugar.jl:263
 [11] top-level scope
    @ REPL[14]:17

On Enzyme v0.13.28. This is a descendant of #1812.

mhauru avatar Jan 07 '25 17:01 mhauru

Could you try #1852 ?

vchuravy avatar Jan 09 '25 08:01 vchuravy

On the latest of that branch (16d5b6583a768c12eb27b5712c20886421d8b080), getting

ERROR: LoadError: UndefVarError: `isvectortype` not defined
Stacktrace:
 [1] include(mod::Module, _path::String)
   @ Base ./Base.jl:495
 [2] include(x::String)
   @ Enzyme.Compiler ~/projects/Enzyme.jl/src/compiler.jl:1
 [3] top-level scope
   @ ~/projects/Enzyme.jl/src/compiler.jl:318
 [4] include(mod::Module, _path::String)
   @ Base ./Base.jl:495
 [5] include(x::String)
   @ Enzyme ~/projects/Enzyme.jl/src/Enzyme.jl:1
 [6] top-level scope
   @ ~/projects/Enzyme.jl/src/Enzyme.jl:127
 [7] include
   @ ./Base.jl:495 [inlined]
 [8] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
   @ Base ./loading.jl:2222
 [9] top-level scope
   @ stdin:3
in expression starting at /Users/mhauru/projects/Enzyme.jl/src/typeutils/recursive_maps.jl:1
in expression starting at /Users/mhauru/projects/Enzyme.jl/src/compiler.jl:1
in expression starting at /Users/mhauru/projects/Enzyme.jl/src/Enzyme.jl:1
in expression starting at stdin:3
  ✗ Enzyme
  0 dependencies successfully precompiled in 3 seconds. 18 already precompiled.

ERROR: The following 1 direct dependency failed to precompile:

Enzyme [7da242da-08ed-463a-9acd-ee780be4f1d9]

Failed to precompile Enzyme [7da242da-08ed-463a-9acd-ee780be4f1d9] to "/Users/mhauru/.julia/compiled/v1.10/Enzyme/jl_Dskjik".
ERROR: LoadError: UndefVarError: `isvectortype` not defined
Stacktrace:
 [1] include(mod::Module, _path::String)
   @ Base ./Base.jl:495
 [2] include(x::String)
   @ Enzyme.Compiler ~/projects/Enzyme.jl/src/compiler.jl:1
 [3] top-level scope
   @ ~/projects/Enzyme.jl/src/compiler.jl:318
 [4] include(mod::Module, _path::String)
   @ Base ./Base.jl:495
 [5] include(x::String)
   @ Enzyme ~/projects/Enzyme.jl/src/Enzyme.jl:1
 [6] top-level scope
   @ ~/projects/Enzyme.jl/src/Enzyme.jl:127
 [7] include
   @ ./Base.jl:495 [inlined]
 [8] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
   @ Base ./loading.jl:2222
 [9] top-level scope
   @ stdin:3
in expression starting at /Users/mhauru/projects/Enzyme.jl/src/typeutils/recursive_maps.jl:1
in expression starting at /Users/mhauru/projects/Enzyme.jl/src/compiler.jl:1
in expression starting at /Users/mhauru/projects/Enzyme.jl/src/Enzyme.jl:1
in expression starting at stdin:
Stacktrace:
  [1] pkgerror(msg::String)
    @ Pkg.Types ~/.julia/juliaup/julia-1.10.6+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/Pkg/src/Types.jl:70
  [2] precompile(ctx::Pkg.Types.Context, pkgs::Vector{…}; internal_call::Bool, strict::Bool, warn_loaded::Bool, already_instantiated::Bool, timing::Bool, _from_loading::Bool, kwargs::@Kwargs{…})
    @ Pkg.API ~/.julia/juliaup/julia-1.10.6+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/Pkg/src/API.jl:1700
  [3] precompile(pkgs::Vector{Pkg.Types.PackageSpec}; io::Base.TTY, kwargs::@Kwargs{_from_loading::Bool})
    @ Pkg.API ~/.julia/juliaup/julia-1.10.6+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/Pkg/src/API.jl:159
  [4] precompile
    @ ~/.julia/juliaup/julia-1.10.6+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/Pkg/src/API.jl:147 [inlined]
  [5] #precompile#114
    @ ~/.julia/juliaup/julia-1.10.6+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/Pkg/src/API.jl:146 [inlined]
  [6] #invokelatest#2
    @ ./essentials.jl:894 [inlined]
  [7] invokelatest
    @ ./essentials.jl:889 [inlined]
  [8] _require(pkg::Base.PkgId, env::String)
    @ Base ./loading.jl:1963
  [9] __require_prelocked(uuidkey::Base.PkgId, env::String)
    @ Base ./loading.jl:1812
 [10] #invoke_in_world#3
    @ ./essentials.jl:926 [inlined]
 [11] invoke_in_world
    @ ./essentials.jl:923 [inlined]
 [12] _require_prelocked(uuidkey::Base.PkgId, env::String)
    @ Base ./loading.jl:1803
 [13] macro expansion
    @ ./loading.jl:1790 [inlined]
 [14] macro expansion
    @ ./lock.jl:267 [inlined]
 [15] __require(into::Module, mod::Symbol)
    @ Base ./loading.jl:1753
 [16] #invoke_in_world#3
    @ ./essentials.jl:926 [inlined]
 [17] invoke_in_world
    @ ./essentials.jl:923 [inlined]
 [18] require(into::Module, mod::Symbol)
    @ Base ./loading.jl:1746
Some type information was truncated. Use `show(err)` to see complete types.

mhauru avatar Jan 09 '25 14:01 mhauru

You need to also pick up the modified EnzymeCore from the same branch:

]dev /Users/mhauru/projects/Enzyme.jl/lib/EnzymeCore

danielwe avatar Jan 09 '25 18:01 danielwe

With that, getting the original Enzyme Mutability Error from OP.

mhauru avatar Jan 10 '25 09:01 mhauru

Oh yeah, #1852 won't make a difference here as the error happens in add_one_in_place but in a separate branch from where recursive_add is called. #1852 only replaces the innards of recursive_add. Clearly, add_one_in_place is being called on an object that's not a RefValue or a zero-dimensional Array.

danielwe avatar Jan 10 '25 16:01 danielwe

The error here is that you're returning an int, which is not a differentiable float type expected by gradient.

We definitely should fix the error message, but that's the core issue here

wsmoses avatar Jan 10 '25 16:01 wsmoses

the error message was already improved, further improved in https://github.com/EnzymeAD/Enzyme.jl/pull/2761

wsmoses avatar Nov 10 '25 08:11 wsmoses