Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 0.42.4

`arraydist` on a vector of univariate distributions now builds its `Distributions.Product` through the inner constructor instead of `Product(dists)`, which is deprecated. The outer constructor calls `Base.depwarn`, and that walks a backtrace on every call, so models with an `arraydist` likelihood paid it once per evaluation. The return type is unchanged.

This restores the behaviour of the DistributionsAD implementation, which used the inner constructor for the same reason before `arraydist` moved here in 0.40.4.

# 0.42.3

Worked around an upstream Julia code-generation bug that, under concurrent allocation load, could crash the model re-evaluation performed by `ParamsWithStats`. The affected re-evaluation is now routed through an internal function barrier that avoids the miscompilation; behaviour is unchanged. The crash was originally reported in [AbstractMCMC.jl#214](https://github.com/TuringLang/AbstractMCMC.jl/issues/214).
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "DynamicPPL"
uuid = "366bfd00-2699-11ea-058f-f148b4cae6d8"
version = "0.42.3"
version = "0.42.4"

[deps]
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
Expand Down
7 changes: 6 additions & 1 deletion src/distribution_wrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,10 @@ function arraydist(dists::AbstractArray{<:Distribution})
return product_distribution(dists)
end
function arraydist(dists::AbstractVector{<:UnivariateDistribution})
return Product(dists)
# The inner constructor skips `Product`'s deprecation warning, which `Base.depwarn`
# makes expensive because it walks a backtrace on every call.
V = typeof(dists)
T = eltype(dists)
S = Distributions.value_support(T)
return Product{S,T,V}(dists)
end
16 changes: 14 additions & 2 deletions test/distribution_wrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ using Dates: now
__now__ = now()

using DynamicPPL: DynamicPPL, @model
using Test: @testset, @test
using Distributions: Normal, logpdf
using Test: @testset, @test, @test_logs
using Distributions: Normal, Product, logpdf, product_distribution
using Bijectors: Bijectors
using StableRNGs: StableRNG

@testset "distribution_wrappers.jl" begin
d = Normal()
Expand All @@ -23,6 +24,17 @@ using Bijectors: Bijectors
@test Bijectors.logpdf_with_trans(nd, 30, true) == 0
end

@testset "arraydist on a vector of univariates" begin
rng = StableRNG(468)
dists = Normal.(randn(rng, 3))
x = randn(rng, 3)
# `Product(v)` calls `Base.depwarn`, which walks a backtrace on every call, so this has
# to go through the inner constructor instead.
@test_logs DynamicPPL.arraydist(dists)
@test DynamicPPL.arraydist(dists) isa Product
@test logpdf(DynamicPPL.arraydist(dists), x) == logpdf(product_distribution(dists), x)
end

@info "Completed $(@__FILE__) in $(now() - __now__)."

end # module
Loading