Skip to content

Enzyme on 1.11 needs more Cache than on 1.10 ? #2288

@yolhan83

Description

@yolhan83

Hello, I encountered an issue in Julia 1.11. I hope it hasn't already been reported (I think #2214 is similar). Here is a minimal working example (MWE):

using Enzyme

function foo(x,y)
    y2 = y.^2
    return sum(x .+ y2[:])
end

x = rand(10)
y = rand(10)
dx = Enzyme.make_zero(x)
dy = Enzyme.make_zero(y)
Enzyme.autodiff(Enzyme.Reverse, foo, Enzyme.Duplicated(x,dx), Enzyme.Const(y))

This works fine on 1.10, however, on 1.11, I get

LoadError: Constant memory is stored (or returned) to a differentiable variable.
As a result, Enzyme cannot provably ensure correctness and throws this error.
This might be due to the use of a constant variable as temporary storage for active memory (https://enzyme.mit.edu/julia/stable/faq/#Runtime-Activity).
If Enzyme should be able to prove this use non-differentable, open an issue!
To work around this issue, either:
 a) rewrite this variable to not be conditionally active (fastest, but requires a code change), or
 b) set the Enzyme mode to turn on runtime activity (e.g. autodiff(set_runtime_activity(Reverse), ...) ). This will maintain correctness, but may slightly reduce performance.
Mismatched activity for:   %38 = phi {} addrspace(10)* [ %29, %L90 ], [ %573, %guard_exit125 ] const val:   %573 = load {} addrspace(10)*, {} addrspace(10)* addrspace(11)* %572, align 8, !dbg !468, !tbaa !104, !alias.scope !40, !noalias !43, !dereferenceable_or_null !221, !align !369, !enzyme_type !68, !enzymejl_source_type_Memory\7BFloat64\7D !0, !enzymejl_byref_MUT_REF !0
 value=Unknown object of type Memory{Float64}
 llvalue=  %573 = load {} addrspace(10)*, {} addrspace(10)* addrspace(11)* %572, align 8, !dbg !468, !tbaa !104, !alias.scope !40, !noalias !43, !dereferenceable_or_null !221, !align !369, !enzyme_type !68, !enzymejl_source_type_Memory\7BFloat64\7D !0, !enzymejl_byref_MUT_REF !0

Stacktrace:
  [1] ==
    @ .\promotion.jl:639
  [2] !=
    @ .\operators.jl:277
  [3] _newindexer
    @ .\broadcast.jl:604
  [4] shapeindexer
    @ .\broadcast.jl:599
  [5] newindexer
    @ .\broadcast.jl:598
  [6] extrude
    @ .\broadcast.jl:645
  [7] preprocess
    @ .\broadcast.jl:953
  [8] preprocess_args (repeats 2 times)
    @ .\broadcast.jl:955
  [9] preprocess
    @ .\broadcast.jl:952
 [10] override_bc_copyto!
    @ C:\Users\yolha\.julia\packages\Enzyme\R6sE8\src\compiler\interpreter.jl:798
 [11] copyto!
    @ .\broadcast.jl:925
 [12] copy
    @ .\broadcast.jl:897
 [13] materialize
    @ .\broadcast.jl:872
 [14] foo
    @ c:\Users\yolha\Desktop\bench_py_jl\mwe_enz.jl:4

Stacktrace:
  [1] unalias
    @ .\abstractarray.jl:1500 [inlined]
  [2] broadcast_unalias
    @ .\broadcast.jl:946 [inlined]
  [3] preprocess
    @ .\broadcast.jl:953 [inlined]
  [4] preprocess_args (repeats 2 times)
    @ .\broadcast.jl:955 [inlined]
  [5] preprocess
    @ .\broadcast.jl:952 [inlined]
  [6] override_bc_copyto!
    @ C:\Users\yolha\.julia\packages\Enzyme\R6sE8\src\compiler\interpreter.jl:798 [inlined]
  [7] copyto!
    @ .\broadcast.jl:925 [inlined]
  [8] copy
    @ .\broadcast.jl:897 [inlined]
  [9] materialize
    @ .\broadcast.jl:872 [inlined]
 [10] foo
    @ c:\Users\yolha\Desktop\bench_py_jl\mwe_enz.jl:4 [inlined]
 [11] diffejulia_foo_12936wrap
    @ c:\Users\yolha\Desktop\bench_py_jl\mwe_enz.jl:0
 [12] top-level scope
    @ c:\Users\yolha\Desktop\bench_py_jl\mwe_enz.jl:12
 [13] eval
    @ .\boot.jl:430 [inlined]
 [14] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base .\loading.jl:2734
 [15] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
    @ Base .\essentials.jl:1055
 [16] invokelatest(::Any, ::Any, ::Vararg{Any})
    @ Base .\essentials.jl:1052
 [17] inlineeval(m::Module, code::String, code_line::Int64, code_column::Int64, file::String; softscope::Bool)
    @ VSCodeServer c:\Users\yolha\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:271
 [18] (::VSCodeServer.var"#69#74"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})()
    @ VSCodeServer c:\Users\yolha\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:181
 [19] withpath(f::VSCodeServer.var"#69#74"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams}, path::String)
    @ VSCodeServer c:\Users\yolha\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\repl.jl:276
 [20] (::VSCodeServer.var"#68#73"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})()
    @ VSCodeServer c:\Users\yolha\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:179
 [21] hideprompt(f::VSCodeServer.var"#68#73"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})
    @ VSCodeServer c:\Users\yolha\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\repl.jl:38
 [22] #67
    @ c:\Users\yolha\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:150 [inlined]
 [23] with_logstate(f::VSCodeServer.var"#67#72"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams}, logstate::Base.CoreLogging.LogState)
    @ Base.CoreLogging .\logging\logging.jl:522
 [24] with_logger
    @ .\logging\logging.jl:632 [inlined]
 [25] (::VSCodeServer.var"#66#71"{VSCodeServer.ReplRunCodeRequestParams})()
    @ VSCodeServer c:\Users\yolha\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:263
 [26] #invokelatest#2
    @ .\essentials.jl:1055 [inlined]
 [27] invokelatest(::Any)
    @ Base .\essentials.jl:1052
 [28] (::VSCodeServer.var"#64#65")()
    @ VSCodeServer c:\Users\yolha\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:34
in expression starting at c:\Users\yolha\Desktop\bench_py_jl\mwe_enz.jl:12

Note that this works if I use Duplicated(NoNeed) for the y variable, also, this is not about squaring, reshape so that too and probaply others.

version :

Julia Version 1.11.3
Commit d63adeda50 (2025-01-21 19:42 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 20 × 12th Gen Intel(R) Core(TM) i7-12700H
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, alderlake)
Threads: 20 default, 0 interactive, 10 GC (on 20 virtual cores)
Environment:
  JULIA_EDITOR = code

on Enzyme v0.13.28
related :
https://discourse.julialang.org/t/zygote-gradient-is-54000-times-slower-than-jax-gradient/125396/43

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions