Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arraydist is showing unintended behavior. #217

Open
krishvishal opened this issue Aug 23, 2020 · 6 comments
Open

arraydist is showing unintended behavior. #217

krishvishal opened this issue Aug 23, 2020 · 6 comments

Comments

@krishvishal
Copy link

krishvishal commented Aug 23, 2020

using Turing, ReverseDiff, LoopVectorization
using ReverseDiff: @grad, TrackedArray

Turing.setadbackend(:reversediff)

logsumexp(x::TrackedArray) = ReverseDiff.track(logsumexp, x) 
@grad function logsumexp(x::AbstractArray)
    lse = logsumexp(ReverseDiff.value(x))
    return lse, Δ ->.* exp.(ReverseDiff.value(x) .- lse),)
end

function logsumexp(mat)
    maxima = vec(vreduce(max, mat, dims=1))'
    exp_mat = @avx exp.(mat .- maxima)
    sum_exp_mat = vreduce(+, exp_mat, dims=1)
    return @avx sum_exp_mat .= maxima .+ log.(sum_exp_mat)
end


@model function mwe(y, A, ::Type{T} = Vector{Float64}) where {T}
    n = size(A, 1)
    scale ~ filldist(Uniform(1, 3), n)
    TT = eltype(scale)
    x ~ arraydist(truncated.(Laplace.(0, scale), TT(-10.0), TT(70.0)))
    println(typeof(x))
    μ = logsumexp(A .- x)[1, :]
    y .~ Normal.(μ, 1)
    return x
end

y1 = rand(10);
A1 = rand(10,10);
model = mwe(y1, A1);
chain = sample(model, NUTS(0.65), 100)

Running the above code results in the following output/error.

Terminal output:

Array{Float64,1}
Array{ReverseDiff.TrackedReal{Float64,Float64,Nothing},1}
ERROR: MethodError: no method matching typemin(::Type{ReverseDiff.TrackedReal{Float64,Float64,Nothing}})
Closest candidates are:
  typemin(::Type{Bool}) at bool.jl:6
  typemin(::Type{Int8}) at int.jl:651
  typemin(::Type{UInt8}) at int.jl:653
  ...

Full stacktrace: https://pastebin.com/hWvFG3sG

The custom adjoint I've defined for logsumexp function expects TrackedArray type but x's type is Array{ReverseDiff.TrackedReal{Float64,Float64,Nothing},1}.

@mohamed82008

@devmotion
Copy link
Member

It seems the error arises from the use of LoopVectorization in your implementation of logsumexp which tries to call typemin which is not defined by ReverseDiff for ::Type{<:TrackedReal}. I guess you could either specify the custom adjoint for Array{<:TrackedReal} or not use LoopVectorization.

@krishvishal
Copy link
Author

Any examples for adjoints of Array{Type}? I don't know how to do that.

@mohamed82008
Copy link
Member

This looks like an issue in DynamicPPL. u should be a TrackedArray here.

@mohamed82008
Copy link
Member

Ok so I narrowed down the problem here to a Bijectors-ReverseDiff issue. The problem is that for the arraydist of truncated Laplace above, the bijector is a TruncatedBijector with array lower and upper bounds. Applying this bijector to a TrackedArray gives an array of TrackedReal. I think this may be fixable.

@mohamed82008
Copy link
Member

julia> using Turing, ReverseDiff

julia> dist = arraydist(truncated.(Laplace.(0, [1, 2]), -10.0, 70.0));

julia> x = ReverseDiff.track(rand(dist));

julia> bijector(dist)(x)
2-element Array{ReverseDiff.TrackedReal{Float64,Float64,Nothing},1}:
 TrackedReal<Fre>(-1.7994654328949322, 0.0, d6k, ---)
 TrackedReal<Ggm>(-1.5788290245320968, 0.0, d6k, ---)

@mohamed82008
Copy link
Member

This TuringLang/Bijectors.jl#142 should fix this issue.

@yebai yebai transferred this issue from TuringLang/Turing.jl Mar 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants