Enzyme.jl
Enzyme.jl copied to clipboard
data corruption in struct
MWE:
using Enzyme
# make a test problem
struct Foo
D::Vector{Float64}
end
const N = 5 # dimension for MWE
(f::Foo)(x) = mapreduce((D, x) -> log(D) + exp(x), +, f.D, x)
ℓ = Foo(fill(2.0, N)) # note the 2.0
ℓ.D # before AD: filled with 2.0s
x = zeros(N)
∂ℓ_∂x = zero(x)
Enzyme.autodiff(Reverse, ℓ, Enzyme.Active, Enzyme.Duplicated(x, ∂ℓ_∂x))
ℓ.D # after AD: filled with 2.5s
(EnzymeMWE) pkg> st
Status `~/research/spouses-time-allocation/tmp/EnzymeMWE/Project.toml`
[7da242da] Enzyme v0.10.17
julia> versioninfo()
Julia Version 1.8.5
Commit 17cfb8e65e* (2023-01-08 06:45 UTC)
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 8 × 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-13.0.1 (ORCJIT, tigerlake)
Threads: 8 on 8 virtual cores
(Issue I mentioned in https://github.com/EnzymeAD/Enzyme.jl/issues/584#issuecomment-1416153125)
Looks like activity analysis cannot get the right answer statically. If you use Enzyme.API.runtimeActivity!(true)
before running it fixes it, but let's leave this open so I can try to update activity analysis.
Is there a way I could rewrite the above to avoid the problem? I am not even sure which part is causing it.
An explicit loop works, eg
function (f::Foo)(x)
T = typeof(log(one(eltype(f.D))) + exp(zero(eltype(x))))
ℓ::T = zero(T)
for (D, x) in zip(f.D, x)
ℓ += log(D) + exp(x)
end
ℓ
end
but calculating types manually is a bit more tedious.
As this now successfully throws a runtime activity error, am going to close (and it succeeds with runtime activity)