Enzyme v0.13.109 broke DI's second-order tests, and it probably has something to do with BatchDuplicated.
using DifferentiationInterface
import Enzyme
arr_to_num(x::AbstractArray) = sum(vec(x .^ 4) .* transpose(vec(x .^ 6)))
function f(x, c)
c[1] = arr_to_num(x)
return c[1]
end
x = [3.0, 5.0];
dx1, dx2 = [1.0, 0.0], [0.0, 1.0];
c = [0.0];
backend = AutoEnzyme()
# works on all Enzyme versions
hvp(f, backend, x, (dx1,), Cache(c))
# works on Enzyme v0.13.108, fails on Enzyme v0.13.109
hvp(f, backend, x, (dx1, dx2), Cache(c))
julia> hvp(f, backend, x, (dx1, dx2), Cache(c))
ERROR: EnzymeRuntimeActivityError: Detected potential need for runtime activity.
Constant memory is stored (or returned) to a differentiable variable and correctness cannot be guaranteed with static activity analysis.
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 performance, slower to setup), 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: %.fca.0.5.insert = insertvalue { { {} addrspace(10)*, {} addrspace(10)*, {} addrspace(10)*, i64, double*, {} addrspace(10)**, double*, double*, double* }, double } %.fca.0.4.insert, {} addrspace(10)** %.sroa.13.0, 0, 5, !dbg !307 const val: %.sroa.13.0 = phi {} addrspace(10)** [ %37, %L113.thread ], [ undef, %L207.loopexit ]
Type tree: {[0]:Pointer, [8]:Pointer, [8,0]:Integer, [8,1]:Integer, [8,2]:Integer, [8,3]:Integer, [8,4]:Integer, [8,5]:Integer, [8,6]:Integer, [8,7]:Integer, [8,8]:Pointer, [8,8,-1]:Float@double, [16]:Pointer, [24]:Integer, [25]:Integer, [26]:Integer, [27]:Integer, [28]:Integer, [29]:Integer, [30]:Integer, [31]:Integer, [32]:Pointer, [32,0]:Float@double, [40]:Pointer, [48]:Anything, [49]:Anything, [50]:Anything, [51]:Anything, [52]:Anything, [53]:Anything, [54]:Anything, [55]:Anything, [56]:Anything, [57]:Anything, [58]:Anything, [59]:Anything, [60]:Anything, [61]:Anything, [62]:Anything, [63]:Anything, [64]:Anything, [65]:Anything, [66]:Anything, [67]:Anything, [68]:Anything, [69]:Anything, [70]:Anything, [71]:Anything, [72]:Anything, [73]:Anything, [74]:Anything, [75]:Anything, [76]:Anything, [77]:Anything, [78]:Anything, [79]:Anything}
LLVM view of erring value: {} addrspace(10)** addrspace(11)* getelementptr inbounds ({ i64, {} addrspace(10)** }, { i64, {} addrspace(10)** } addrspace(11)* addrspacecast ({ i64, {} addrspace(10)** } addrspace(10)* bitcast ({} addrspace(10)* @"ejl_inserted$_Core_GenericMemory_24896$true$4744527424" to { i64, {} addrspace(10)** } addrspace(10)*) to { i64, {} addrspace(10)** } addrspace(11)*), i64 0, i32 1)
Stacktrace:
[1] sum
@ ./reducedim.jl:982
[2] arr_to_num
@ ./REPL[54]:1
Stacktrace:
[1] sum
@ ./reducedim.jl:982 [inlined]
[2] arr_to_num
@ ./REPL[54]:1
[3] f
@ ./REPL[55]:2 [inlined]
[4] diffejulia_f_24869wrap
@ ./REPL[55]:0 [inlined]
[5] macro expansion
@ ~/.julia/packages/Enzyme/i91IH/src/compiler.jl:6652 [inlined]
[6] enzyme_call
@ ~/.julia/packages/Enzyme/i91IH/src/compiler.jl:6131 [inlined]
[7] CombinedAdjointThunk
@ ~/.julia/packages/Enzyme/i91IH/src/compiler.jl:6015 [inlined]
[8] autodiff
@ ~/.julia/packages/Enzyme/i91IH/src/Enzyme.jl:521 [inlined]
[9] autodiff
@ ~/.julia/packages/Enzyme/i91IH/src/Enzyme.jl:542 [inlined]
[10] gradient
@ ~/.julia/packages/DifferentiationInterface/4n6vR/ext/DifferentiationInterfaceEnzymeExt/reverse_onearg.jl:303 [inlined]
[11] gradient
@ ~/.julia/packages/DifferentiationInterface/4n6vR/src/first_order/gradient.jl:63
[12] shuffled_gradient
@ ~/.julia/packages/DifferentiationInterface/4n6vR/src/first_order/gradient.jl:160 [inlined]
[13] fwddiffe2julia_shuffled_gradient_25033wrap
@ ~/.julia/packages/DifferentiationInterface/4n6vR/src/first_order/gradient.jl:0
[14] macro expansion
@ ~/.julia/packages/Enzyme/i91IH/src/compiler.jl:6652 [inlined]
[15] enzyme_call
@ ~/.julia/packages/Enzyme/i91IH/src/compiler.jl:6131 [inlined]
[16] ForwardModeThunk
@ ~/.julia/packages/Enzyme/i91IH/src/compiler.jl:6031 [inlined]
[17] autodiff
@ ~/.julia/packages/Enzyme/i91IH/src/Enzyme.jl:673 [inlined]
[18] autodiff
@ ~/.julia/packages/Enzyme/i91IH/src/Enzyme.jl:562 [inlined]
[19] autodiff
@ ~/.julia/packages/Enzyme/i91IH/src/Enzyme.jl:534 [inlined]
[20] pushforward
@ ~/.julia/packages/DifferentiationInterface/4n6vR/ext/DifferentiationInterfaceEnzymeExt/forward_onearg.jl:94 [inlined]
[21] hvp
@ ~/.julia/packages/DifferentiationInterface/4n6vR/src/second_order/hvp.jl:331 [inlined]
[22] hvp(f::typeof(f), backend::AutoEnzyme{…}, x::Vector{…}, tx::Tuple{…}, contexts::Cache{…})
@ DifferentiationInterface ~/.julia/packages/DifferentiationInterface/4n6vR/src/second_order/hvp.jl:75
[23] top-level scope
@ REPL[61]:1
Some type information was truncated. Use `show(err)` to see complete types.
Enzyme v0.13.109 broke DI's second-order tests, and it probably has something to do with
BatchDuplicated.Here's a DI-based MWE while I extract its non-DI counterpart:
Stack trace:
Environment: