Releases: TuringLang/DynamicPPL.jl
v0.35.2
DynamicPPL v0.35.2
unflatten(::VarInfo, params)
now works with params that have non-float types (such as Int or Bool).
v0.35.1
DynamicPPL v0.35.1
subset(::AbstractVarInfo, ::AbstractVector{<:VarName})
now preserves the ordering of the varnames in the original varinfo argument.
Previously, this would select the varnames according to their order in the second argument.
This fixes an upstream Turing.jl issue with Gibbs sampling when a component sampler was assigned multiple variables.
Merged pull requests:
- CompatHelper: bump compat for Zygote to 0.7 for package test, (keep existing compat) (#771) (@github-actions[bot])
- Update benchmark models (#826) (@mhauru)
- CompatHelper: bump compat for DocumenterMermaid to 0.2 for package docs, (keep existing compat) (#831) (@github-actions[bot])
- Make benchmarks not depend on TuringBenchmarking.jl, and run
]dev ..
(#834) (@mhauru) - Removed Zygote tests (#837) (@shravanngoswamii)
Closed issues:
v0.35.0
DynamicPPL v0.35.0
Breaking changes
.~
right hand side must be a univariate distribution
Previously we allowed statements like
x .~ [Normal(), Gamma()]
where the right hand side of a .~
was an array of distributions, and ones like
x .~ MvNormal(fill(0.0, 2), I)
where the right hand side was a multivariate distribution.
These are no longer allowed. The only things allowed on the right hand side of a .~
statement are univariate distributions, such as
x = Array{Float64,3}(undef, 2, 3, 4)
x .~ Normal()
The reasons for this are internal code simplification and the fact that broadcasting where both sides are multidimensional but of different dimensions is typically confusing to read.
If the right hand side and the left hand side have the same dimension, one can simply use ~
. Arrays of distributions can be replaced with product_distribution
. So instead of
x .~ [Normal(), Gamma()]
x .~ Normal.(y)
x .~ MvNormal(fill(0.0, 2), I)
do
x ~ product_distribution([Normal(), Gamma()])
x ~ product_distribution(Normal.(y))
x ~ MvNormal(fill(0.0, 2), I)
This is often more performant as well. Note that using ~
rather than .~
does change the internal storage format a bit: With .~
x[i]
are stored as separate variables, with ~
as a single multivariate variable x
. In most cases this does not change anything for the user, but if it does cause issues, e.g. if you are dealing with VarInfo
objects directly and need to keep the old behavior, you can always expand into a loop, such as
dists = Normal.(y)
for i in 1:length(dists)
x[i] ~ dists[i]
end
Cases where the right hand side is of a different dimension than the left hand side, and neither is a scalar, must be replaced with a loop. For example,
x = Array{Float64,3}(undef, 2, 3, 4)
x .~ MvNormal(fill(0, 2), I)
should be replaced with something like
x = Array{Float64,3}(2, 3, 4)
for i in 1:3, j in 1:4
x[:, i, j] ~ MvNormal(fill(0, 2), I)
end
This release also completely rewrites the internal implementation of .~
, where from now on all .~
statements are turned into loops over ~
statements at macro time. However, the only breaking aspect of this change is the above change to what's allowed on the right hand side.
Remove indexing by samplers
This release removes the feature of VarInfo
where it kept track of which variable was associated with which sampler. This means removing all user-facing methods where VarInfo
s where being indexed with samplers. In particular,
link
andinvlink
, and their!!
versions, no longer accept a sampler as an argument to specify which variables to (inv)link. Thelink(varinfo, model)
methods remain in place, and as a new addition one can give aTuple
ofVarName
s to (inv)link only select variables, as inlink(varinfo, varname_tuple, model)
.set_retained_vns_del_by_spl!
has been replaced byset_retained_vns_del!
which applies to all variables.getindex
,setindex!
, andsetindex!!
no longer accept samplers as argumentsunflatten
no longer accepts a sampler as an argumenteltype(::VarInfo)
no longer accepts a sampler as an argumentkeys(::VarInfo)
no longer accepts a sampler as an argumentVarInfo(::VarInfo, ::Sampler, ::AbstractVector)
no longer accepts the sampler argument.push!!
andpush!
no longer accept samplers orSelector
s as argumentsgetgid
,setgid!
,updategid!
,getspace
, andinspace
no longer exist
Reverse prefixing order
-
For submodels constructed using
to_submodel
, the order in which nested prefixes are applied has been changed.
Previously, the order was that outer prefixes were applied first, then inner ones.
This version reverses that.
To illustrate:using DynamicPPL, Distributions @model function subsubmodel() return x ~ Normal() end @model function submodel() x ~ to_submodel(prefix(subsubmodel(), :c), false) return x end @model function parentmodel() x1 ~ to_submodel(prefix(submodel(), :a), false) return x2 ~ to_submodel(prefix(submodel(), :b), false) end keys(VarInfo(parentmodel()))
Previously, the final line would return the variable names
c.a.x
andc.b.x
.
With this version, it will returna.c.x
andb.c.x
, which is more intuitive.
(Note that this change bringsto_submodel
's behaviour in line with the now-deprecated@submodel
macro.)This change also affects sampling in Turing.jl.
LogDensityFunction
argument order
- The method
LogDensityFunction(varinfo, model, sampler)
has been removed.
The only accepted order isLogDensityFunction(model, varinfo, context; adtype)
.
(For an explanation ofadtype
, see below.)
The varinfo and context arguments are both still optional.
Other changes
New exports
LogDensityFunction
and predict
are now exported from DynamicPPL.
LogDensityProblems
interface
LogDensityProblemsAD is now removed as a dependency.
Instead of constructing a LogDensityProblemAD.ADgradient
object, we now directly use DifferentiationInterface
to calculate the gradient of the log density with respect to model parameters.
Note that if you wish, you can still construct an ADgradient
out of a LogDensityFunction
object (there is nothing preventing this).
However, in this version, LogDensityFunction
now takes an extra AD type argument.
If this argument is not provided, the behaviour is exactly the same as before, i.e. you can calculate logdensity
but not its gradient.
However, if you do pass an AD type, that will allow you to calculate the gradient as well.
You may thus find that it is easier to instead do this:
@model f() = ...
ldf = LogDensityFunction(f(); adtype=AutoForwardDiff())
This will return an object which satisfies the LogDensityProblems
interface to first-order, i.e. you can now directly call both
LogDensityProblems.logdensity(ldf, params)
LogDensityProblems.logdensity_and_gradient(ldf, params)
without having to construct a separate ADgradient
object.
If you prefer, you can also construct a new LogDensityFunction
with a new AD type afterwards.
The model, varinfo, and context will be taken from the original LogDensityFunction
:
Merged pull requests:
- Remove selector stuff from VarInfo tests and link/invlink (#780) (@mhauru)
- Reverse order of prefixing & add changelog (#792) (@penelopeysm)
- Remove samplers from VarInfo - indexing (#793) (@mhauru)
- Redirect transformation to main docs (#798) (@penelopeysm)
- Run Docs and Format workflows on all PRs (#800) (@penelopeysm)
- Remove dot_tilde pipeline (#804) (@mhauru)
- Update GHA to use shared org actions (#805) (@penelopeysm)
- Remove LogDensityProblemsAD; wrap adtype in LogDensityFunction (#806) (@penelopeysm)
- Remove samplers from VarInfo - Selectors and GIDs (#808) (@mhauru)
- Bump KernelAbstractions to 0.9.33 (#809) (@penelopeysm)
- Remove LogDensityProblemsAD Extension 2 (#811) (@penelopeysm)
- Remove x86 CI (#819) (@penelopeysm)
- Export
LogDensityFunction
(#820) (@penelopeysm) - Export
predict
with 0.35 (#821) (@sunxd3) - Fix predict docstring (#822) (@penelopeysm)
Closed issues:
.~
seems to give incorrect answers (#28)- Error with
.~
andrand
(#405) - Should we have a context to indicate that we're not performing inference? (#510)
- Sampling from model prior with
missing
is thread-unsafe (#641) - Decide the fate of
VarInfo.num_produce
(#661) - Support for variables with changing size with
dot_tilde
(#700) - Move transformation docs to docs (#713)
- Confusion regarding
.~
(#722) - Issues with the dot-tilde (i.e.
.~
) syntax (#761) - Update GHA (#803)
- Submodels (#807)
v0.34.2
DynamicPPL v0.34.2
- Fixed bugs in ValuesAsInModelContext as well as DebugContext where underlying PrefixContexts were not being applied. From a user-facing perspective, this means that for models which use manually prefixed submodels, e.g.
using DynamicPPL, Distributions
@model inner() = x ~ Normal()
@model function outer()
x1 ~ to_submodel(prefix(inner(), :a), false)
x2 ~ to_submodel(prefix(inner(), :b), false)
end
will: (1) no longer error when sampling due to check_model_and_trace
; and (2) contain both submodel's variables in the resulting chain (the behaviour before this patch was that the second x
would override the first x
).
- More broadly, implemented a general
prefix(ctx::AbstractContext, ::VarName)
which traverses the context tree inctx
to apply all necessary prefixes. This was a necessary step in fixing the above issues, but it also means thatprefix
is now capable of handling context trees with e.g. multiple prefixes at different levels of nesting.
Merged pull requests:
- Expand JET test (#782) (@penelopeysm)
- Clarify is_unconstrained docstring (#790) (@penelopeysm)
v0.34.1
DynamicPPL v0.34.1
Fix an issue that prevented merging two VarInfos if they had different dimensions for a variable.
Upper bound the compat version of KernelAbstractions to work around an issue in determining the right VarInfo type to use.
v0.34.0
DynamicPPL v0.34.0
Breaking changes
-
rng
argument removed fromvalues_as_in_model
, andvarinfo
made non-optional. This means that the only signatures allowed arevalues_as_in_model(::Model, ::Bool, ::AbstractVarInfo) values_as_in_model(::Model, ::Bool, ::AbstractVarInfo, ::AbstractContext)
If you aren't using this function (it's probably only used in Turing.jl) then this won't affect you.
v0.33.1
DynamicPPL v0.33.1
- Reworked internals of
condition
anddecondition
. There are no changes to the public-facing API, but internally you can no longer usecondition
anddecondition
on an AbstractContext, you can only use it on aDynamicPPL.Model
. If you want to modify a context, useConditionContext
anddecondition_context
.
v0.33.0
DynamicPPL v0.33.0
Breaking changes
values_as_in_model()
now requires an extra boolean parameter, specifying whether variables on the lhs of:=
statements are to be included in the resulting OrderedDict of values. The type signature is nowvalues_as_in_model([rng,] model, include_colon_eq::Bool [, varinfo, context])
Other changes
- Moved the implementation of
predict
from Turing.jl to DynamicPPL.jl; the user-facing behaviour is otherwise the same - Improved error message when a user tries to initialise a model with parameters that don't correspond strictly to the underlying VarInfo used
Merged pull requests:
- Move
predict
from Turing (#716) (@sunxd3) - Don't include lhs of := in results of predict() (#766) (@penelopeysm)
- Remove extra doctest filters (#769) (@penelopeysm)
Closed issues:
- Taking stochastic control flow a bit more seriously (#25)
- Adopt DensityInterface (#340)
- Remove
NamedDist
in favour ofVarName
interpolation (#400) - Simplify
assume
/observe
design (#402) - Supporting mutating ADs in models that fill arrays of parameters (#412)
- Name clash caused by submodels is hard to debug (#427)
- Decouple from Distributions.jl (#523)
- Move TestUtils to an extension (#550)
- Issue with ReverseDiff and undef on Julia v1.7 (#612)
- Transfer
Turing.Inference.predict
toDynamicPPL
. (#647) - Distributions with latent variables (#689)
- Chain returned by
predict
will contain variables used in:=
statements (#765) - Remove unneeded doctest filters and fix tests (#768)
- Do
from_internal_transform()
etc. requirevi
andvn
as arguments? (#773)
v0.32.2
v0.32.1
DynamicPPL v0.32.1
Merged pull requests:
- Make CI + tests more efficient (#749) (@penelopeysm)
- Remove duplicated tests (#753) (@penelopeysm)
- CompatHelper: add new compat entry for OrderedCollections at version 1 for package test, (keep existing compat) (#754) (@github-actions[bot])
Closed issues:
- x86 2threads ubuntu CI OOM failure (#725)