Bounds error when analyzing typeunstablerules.jl
I found a strange bug that appears to be in the Enzyme-type unstable rules for Julia. Here is a somewhat MWE I constructed from some stripped down code.
using Enzyme
Enzyme.API.runtimeActivity!(true) #Otherwise Enzyme complains about ProductDist
struct Uniform{T}
a::T
b::T
end
logpdf(d::Uniform, ::Real) = -log(d.b - d.a)
struct Normal{T}
μ::T
σ::T
end
logpdf(d::Normal, x::Real) = -(x - d.μ)^2 / (2 * d.σ^2)
struct ProductDist{V}
dists::V
end
function logpdf(d::ProductDist, x::Vector)
dists = d.dists
s = zero(eltype(x))
for i in eachindex(x)
s += logpdf(dists[i], x[i])
end
return s
end
struct NamedDist{Names, D<:NamedTuple{Names}}
dists::D
end
function logpdf(d::NamedDist{N}, x::NamedTuple{N}) where {N}
vt = values(x)
dists = d.dists
return mapreduce((dist, acc) -> logpdf(dist, acc), +, dists, vt)
end
d = NamedDist((;a = Normal(0.0, 1.0), b = ProductDist([Uniform(0.0, 1.0), Uniform(0.0, 1.0)])))
p = (a = 1.0, b = [0.5, 0.5])
dp = Enzyme.make_zero(p)
logpdf(d, p)
autodiff(Reverse, logpdf, Active, Const(d), Duplicated(p, dp))
The stacktrace on my machine is
ERROR: BoundsError: attempt to access Base.RefValue{@NamedTuple{a::Normal{Float64}, b::ProductDist{Vector{Uniform{Float64}}}}} at index [2]
Stacktrace:
[1] getfield_idx
@ ~/.julia/packages/Enzyme/qRjan/src/rules/typeunstablerules.jl:228 [inlined]
[2] idx_jl_getfield_aug(::Base.RefValue{@NamedTuple{a::Normal{…}, b::ProductDist{…}}}, ::Type{Val{1}}, ::Val{false})
@ Enzyme.Compiler ~/.julia/packages/Enzyme/qRjan/src/rules/typeunstablerules.jl:250
[3] iterate
@ ./namedtuple.jl:165 [inlined]
[4] _zip_iterate_some
@ ./iterators.jl:428 [inlined]
[5] _zip_iterate_all
@ ./iterators.jl:420 [inlined]
[6] iterate
@ ./iterators.jl:411 [inlined]
[7] _foldl_impl
@ ./reduce.jl:60
[8] foldl_impl
@ ./reduce.jl:48 [inlined]
[9] mapfoldl_impl
@ ./reduce.jl:44 [inlined]
[10] mapfoldl
@ ./reduce.jl:175 [inlined]
[11] mapreduce
@ ./reduce.jl:307 [inlined]
[12] reduce
@ ./reduce.jl:490 [inlined]
[13] mapreduce
@ ./reduce.jl:308 [inlined]
[14] logpdf
@ ~/.julia/dev/VLBIImagePriors/enzyme_test.jl:35 [inlined]
[15] logpdf
@ ~/.julia/dev/VLBIImagePriors/enzyme_test.jl:0 [inlined]
[16] diffejulia_logpdf_4733_inner_1wrap
@ ~/.julia/dev/VLBIImagePriors/enzyme_test.jl:0
[17] macro expansion
@ ~/.julia/packages/Enzyme/qRjan/src/compiler.jl:5377 [inlined]
[18] enzyme_call(::Val{…}, ::Ptr{…}, ::Type{…}, ::Type{…}, ::Val{…}, ::Type{…}, ::Type{…}, ::Const{…}, ::Type{…}, ::Const{…}, ::Duplicated{…}, ::Float64)
@ Enzyme.Compiler ~/.julia/packages/Enzyme/qRjan/src/compiler.jl:5055
[19] (::Enzyme.Compiler.CombinedAdjointThunk{…})(::Const{…}, ::Const{…}, ::Vararg{…})
@ Enzyme.Compiler ~/.julia/packages/Enzyme/qRjan/src/compiler.jl:4997
[20] autodiff(::ReverseMode{false, FFIABI}, ::Const{typeof(logpdf)}, ::Type{Active}, ::Const{NamedDist{…}}, ::Vararg{Any})
@ Enzyme ~/.julia/packages/Enzyme/qRjan/src/Enzyme.jl:215
[21] autodiff(::ReverseMode{false, FFIABI}, ::typeof(logpdf), ::Type, ::Const{NamedDist{…}}, ::Vararg{Any})
@ Enzyme ~/.julia/packages/Enzyme/qRjan/src/Enzyme.jl:224
[22] top-level scope
I am on Julia 1.10.1 and using [email protected]
Ah so this one shouldn’t be bad, in essence that code should check if the value is a ref, deref and update the value, then store it back
On Thu, Feb 29, 2024 at 8:28 AM Paul Tiede @.***> wrote:
I found a strange bug that appears to be in the Enzyme-type unstable rules for Julia. Here is a somewhat MWE I constructed from some stripped down code.
using Enzyme Enzyme.API.runtimeActivity!(true) #Otherwise Enzyme complains about ProductDist struct Uniform{T} a::T b::Tendlogpdf(d::Uniform, ::Real) = -log(d.b - d.a) struct Normal{T} μ::T σ::Tendlogpdf(d::Normal, x::Real) = -(x - d.μ)^2 / (2 * d.σ^2) struct ProductDist{V} dists::Vendfunction logpdf(d::ProductDist, x::Vector) dists = d.dists s = zero(eltype(x)) for i in eachindex(x) s += logpdf(dists[i], x[i]) end return send struct NamedDist{Names, D<:NamedTuple{Names}} dists::Dend function logpdf(d::NamedDist{N}, x::NamedTuple{N}) where {N} vt = values(x) dists = d.dists return mapreduce((dist, acc) -> logpdf(dist, acc), +, dists, vt)end
d = NamedDist((;a = Normal(0.0, 1.0), b = ProductDist([Uniform(0.0, 1.0), Uniform(0.0, 1.0)]))) p = (a = 1.0, b = [0.5, 0.5]) dp = Enzyme.make_zero(p)logpdf(d, p)autodiff(Reverse, logpdf, Active, Const(d), Duplicated(p, dp))
The stacktrace on my machine is
ERROR: BoundsError: attempt to access @.{a::Normal{Float64}, b::ProductDist{Vector{Uniform{Float64}}}}} at index [2] Stacktrace: [1] getfield_idx @ ~/.julia/packages/Enzyme/qRjan/src/rules/typeunstablerules.jl:228 [inlined] [2] @.{a::Normal{…}, b::ProductDist{…}}}, ::Type{Val{1}}, ::Val{false}) @ Enzyme.Compiler ~/.julia/packages/Enzyme/qRjan/src/rules/typeunstablerules.jl:250 [3] iterate @ ./namedtuple.jl:165 [inlined] [4] _zip_iterate_some @ ./iterators.jl:428 [inlined] [5] _zip_iterate_all @ ./iterators.jl:420 [inlined] [6] iterate @ ./iterators.jl:411 [inlined] [7] _foldl_impl @ ./reduce.jl:60 [8] foldl_impl @ ./reduce.jl:48 [inlined] [9] mapfoldl_impl @ ./reduce.jl:44 [inlined] [10] mapfoldl @ ./reduce.jl:175 [inlined] [11] mapreduce @ ./reduce.jl:307 [inlined] [12] reduce @ ./reduce.jl:490 [inlined] [13] mapreduce @ ./reduce.jl:308 [inlined] [14] logpdf @ ~/.julia/dev/VLBIImagePriors/enzyme_test.jl:35 [inlined] [15] logpdf @ ~/.julia/dev/VLBIImagePriors/enzyme_test.jl:0 [inlined] [16] diffejulia_logpdf_4733_inner_1wrap @ ~/.julia/dev/VLBIImagePriors/enzyme_test.jl:0 [17] macro expansion @ ~/.julia/packages/Enzyme/qRjan/src/compiler.jl:5377 [inlined] [18] enzyme_call(::Val{…}, ::Ptr{…}, ::Type{…}, ::Type{…}, ::Val{…}, ::Type{…}, ::Type{…}, ::Const{…}, ::Type{…}, ::Const{…}, ::Duplicated{…}, ::Float64) @ Enzyme.Compiler ~/.julia/packages/Enzyme/qRjan/src/compiler.jl:5055 [19] (::Enzyme.Compiler.CombinedAdjointThunk{…})(::Const{…}, ::Const{…}, ::Vararg{…}) @ Enzyme.Compiler ~/.julia/packages/Enzyme/qRjan/src/compiler.jl:4997 [20] autodiff(::ReverseMode{false, FFIABI}, ::Const{typeof(logpdf)}, ::Type{Active}, ::Const{NamedDist{…}}, ::Vararg{Any}) @ Enzyme ~/.julia/packages/Enzyme/qRjan/src/Enzyme.jl:215 [21] autodiff(::ReverseMode{false, FFIABI}, ::typeof(logpdf), ::Type, ::Const{NamedDist{…}}, ::Vararg{Any}) @ Enzyme ~/.julia/packages/Enzyme/qRjan/src/Enzyme.jl:224 [22] top-level scope
I am on Julia 1.10.1 and using @.***
— Reply to this email directly, view it on GitHub https://github.com/EnzymeAD/Enzyme.jl/issues/1317, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJTUXHARHCHUCZ4CAPEPN3YV5LLTAVCNFSM6AAAAABEAIC7V2VHI2DSMVQWIX3LMV43ASLTON2WKOZSGE3DCNRUGQ4TSMA . You are receiving this because you are subscribed to this thread.Message ID: @.***>
should be fixed by https://github.com/EnzymeAD/Enzyme.jl/pull/1430