Skip to content

Commit 23834de

Browse files
penelopeysmmhauruyebai
authored
Release 0.36 (#829)
* Release 0.36 * AbstractPPL 0.11 + change prefixing behaviour (#830) * AbstractPPL 0.11; change prefixing behaviour * Use DynamicPPL.prefix rather than overloading * Remove VarInfo(VarInfo, params) (#870) * Unify `{untyped,typed}_{vector_,}varinfo` constructor functions (#879) * Unify {Untyped,Typed}{Vector,}VarInfo constructors * Update invocations * NTVarInfo * Fix tests * More fixes * Fixes * Fixes * Fixes * Use lowercase functions, don't deprecate VarInfo * Rewrite VarInfo docstring * Fix methods * Fix methods (really) * Link varinfo by default in AD testing utilities; make test suite run on linked varinfos (#890) * Link VarInfo by default * Tweak interface * Fix tests * Fix interface so that callers can inspect results * Document * Fix tests * Fix changelog * Test linked varinfos Closes #891 * Fix docstring + use AbstractFloat * Fix `condition` and `fix` in submodels (#892) * Fix conditioning in submodels * Simplify contextual_isassumption * Add documentation * Fix some tests * Add tests; fix a bunch of nested submodel issues * Fix fix as well * Fix doctests * Add unit tests for new functions * Add changelog entry * Update changelog Co-authored-by: Hong Ge <3279477+yebai@users.noreply.github.com> * Finish docs * Add a test for conditioning submodel via arguments * Clean new tests up a bit * Fix for VarNames with non-identity lenses * Apply suggestions from code review Co-authored-by: Markus Hauru <markus@mhauru.org> * Apply suggestions from code review * Make PrefixContext contain a varname rather than symbol (#896) --------- Co-authored-by: Hong Ge <3279477+yebai@users.noreply.github.com> Co-authored-by: Markus Hauru <markus@mhauru.org> --------- Co-authored-by: Markus Hauru <mhauru@turing.ac.uk> Co-authored-by: Hong Ge <3279477+yebai@users.noreply.github.com> Co-authored-by: Markus Hauru <markus@mhauru.org>
1 parent cb4ea95 commit 23834de

37 files changed

+1741
-606
lines changed

HISTORY.md

+134
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,139 @@
11
# DynamicPPL Changelog
22

3+
## 0.36.0
4+
5+
**Breaking changes**
6+
7+
### Submodels: conditioning
8+
9+
Variables in a submodel can now be conditioned and fixed in a correct way.
10+
See https://github.com/TuringLang/DynamicPPL.jl/issues/857 for a full illustration, but essentially it means you can now do this:
11+
12+
```julia
13+
@model function inner()
14+
x ~ Normal()
15+
return y ~ Normal()
16+
end
17+
@model function outer()
18+
return a ~ to_submodel(inner() | (x=1.0,))
19+
end
20+
```
21+
22+
and the `a.x` variable will be correctly conditioned.
23+
(Previously, you would have to condition `inner()` with the variable `a.x`, meaning that you would need to know what prefix to use before you had actually prefixed it.)
24+
25+
### Submodel prefixing
26+
27+
The way in which VarNames in submodels are prefixed has been changed.
28+
This is best explained through an example.
29+
Consider this model and submodel:
30+
31+
```julia
32+
using DynamicPPL, Distributions
33+
@model inner() = x ~ Normal()
34+
@model outer() = a ~ to_submodel(inner())
35+
```
36+
37+
In previous versions, the inner variable `x` would be saved as `a.x`.
38+
However, this was represented as a single symbol `Symbol("a.x")`:
39+
40+
```julia
41+
julia> dump(keys(VarInfo(outer()))[1])
42+
VarName{Symbol("a.x"), typeof(identity)}
43+
optic: identity (function of type typeof(identity))
44+
```
45+
46+
Now, the inner variable is stored as a field `x` on the VarName `a`:
47+
48+
```julia
49+
julia> dump(keys(VarInfo(outer()))[1])
50+
VarName{:a, Accessors.PropertyLens{:x}}
51+
optic: Accessors.PropertyLens{:x} (@o _.x)
52+
```
53+
54+
In practice, this means that if you are trying to condition a variable in the submodel, you now need to use
55+
56+
```julia
57+
outer() | (@varname(a.x) => 1.0,)
58+
```
59+
60+
instead of either of these (which would have worked previously)
61+
62+
```julia
63+
outer() | (@varname(var"a.x") => 1.0,)
64+
outer() | (a.x=1.0,)
65+
```
66+
67+
In a similar way, if the variable on the left-hand side of your tilde statement is not just a single identifier, any fields or indices it accesses are now properly respected.
68+
Consider the following setup:
69+
70+
```julia
71+
using DynamicPPL, Distributions
72+
@model inner() = x ~ Normal()
73+
@model function outer()
74+
a = Vector{Float64}(undef, 1)
75+
a[1] ~ to_submodel(inner())
76+
return a
77+
end
78+
```
79+
80+
In this case, the variable sampled is actually the `x` field of the first element of `a`:
81+
82+
```julia
83+
julia> only(keys(VarInfo(outer()))) == @varname(a[1].x)
84+
true
85+
```
86+
87+
Before this version, it used to be a single variable called `var"a[1].x"`.
88+
89+
Note that if you are sampling from a model with submodels, this doesn't affect the way you interact with the `MCMCChains.Chains` object, because VarNames are converted into Symbols when stored in the chain.
90+
(This behaviour will likely be changed in the future, in that Chains should be indexable by VarNames and not just Symbols, but that has not been implemented yet.)
91+
92+
### AD testing utilities
93+
94+
`DynamicPPL.TestUtils.AD.run_ad` now links the VarInfo by default.
95+
To disable this, pass the `linked=false` keyword argument.
96+
If the calculated value or gradient is incorrect, it also throws a `DynamicPPL.TestUtils.AD.ADIncorrectException` rather than a test failure.
97+
This exception contains the actual and expected gradient so you can inspect it if needed; see the documentation for more information.
98+
From a practical perspective, this means that if you need to add this to a test suite, you need to use `@test run_ad(...) isa Any` rather than just `run_ad(...)`.
99+
100+
### SimpleVarInfo linking / invlinking
101+
102+
Linking a linked SimpleVarInfo, or invlinking an unlinked SimpleVarInfo, now displays a warning instead of an error.
103+
104+
### VarInfo constructors
105+
106+
`VarInfo(vi::VarInfo, values)` has been removed. You can replace this directly with `unflatten(vi, values)` instead.
107+
108+
The `metadata` argument to `VarInfo([rng, ]model[, sampler, context, metadata])` has been removed.
109+
If you were not using this argument (most likely), then there is no change needed.
110+
If you were using the `metadata` argument to specify a blank `VarNamedVector`, then you should replace calls to `VarInfo` with `DynamicPPL.typed_vector_varinfo` instead (see 'Other changes' below).
111+
112+
The `UntypedVarInfo` constructor and type is no longer exported.
113+
If you needed to construct one, you should now use `DynamicPPL.untyped_varinfo` instead.
114+
115+
The `TypedVarInfo` constructor and type is no longer exported.
116+
The _type_ has been replaced with `DynamicPPL.NTVarInfo`.
117+
The _constructor_ has been replaced with `DynamicPPL.typed_varinfo`.
118+
119+
Note that the exact kind of VarInfo returned by `VarInfo(rng, model, ...)` is an implementation detail.
120+
Previously, it was guaranteed that this would always be a VarInfo whose metadata was a `NamedTuple` containing `Metadata` structs.
121+
Going forward, this is no longer the case, and you should only assume that the returned object obeys the `AbstractVarInfo` interface.
122+
123+
**Other changes**
124+
125+
While these are technically breaking, they are only internal changes and do not affect the public API.
126+
The following four functions have been added and/or reworked to make it easier to construct VarInfos with different types of metadata:
127+
128+
1. `DynamicPPL.untyped_varinfo([rng, ]model[, sampler, context])`
129+
2. `DynamicPPL.typed_varinfo([rng, ]model[, sampler, context])`
130+
3. `DynamicPPL.untyped_vector_varinfo([rng, ]model[, sampler, context])`
131+
4. `DynamicPPL.typed_vector_varinfo([rng, ]model[, sampler, context])`
132+
133+
The reason for this change is that there were several flavours of VarInfo.
134+
Some, like `typed_varinfo`, were easy to construct because we had convenience methods for them; however, the others were more difficult.
135+
This change makes it easier to access different VarInfo types, and also makes it more explicit which one you are constructing.
136+
3137
## 0.35.9
4138

5139
Fixed the `isnan` check introduced in 0.35.7 for distributions which returned NamedTuple.

Project.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "DynamicPPL"
22
uuid = "366bfd00-2699-11ea-058f-f148b4cae6d8"
3-
version = "0.35.9"
3+
version = "0.36.0"
44

55
[deps]
66
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
@@ -46,7 +46,7 @@ DynamicPPLMooncakeExt = ["Mooncake"]
4646
[compat]
4747
ADTypes = "1"
4848
AbstractMCMC = "5"
49-
AbstractPPL = "0.10.1"
49+
AbstractPPL = "0.11"
5050
Accessors = "0.1"
5151
BangBang = "0.4.1"
5252
Bijectors = "0.13.18, 0.14, 0.15"

benchmarks/src/DynamicPPLBenchmarks.jl

+4-6
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ end
5252
5353
Create a benchmark suite for `model` using the selected varinfo type and AD backend.
5454
Available varinfo choices:
55-
• `:untyped` → uses `VarInfo()`
56-
• `:typed` → uses `VarInfo(model)`
55+
• `:untyped` → uses `DynamicPPL.untyped_varinfo(model)`
56+
• `:typed` → uses `DynamicPPL.typed_varinfo(model)`
5757
• `:simple_namedtuple` → uses `SimpleVarInfo{Float64}(model())`
5858
• `:simple_dict` → builds a `SimpleVarInfo{Float64}` from a Dict (pre-populated with the model’s outputs)
5959
@@ -67,11 +67,9 @@ function make_suite(model, varinfo_choice::Symbol, adbackend::Symbol, islinked::
6767
suite = BenchmarkGroup()
6868

6969
vi = if varinfo_choice == :untyped
70-
vi = VarInfo()
71-
model(rng, vi)
72-
vi
70+
DynamicPPL.untyped_varinfo(rng, model)
7371
elseif varinfo_choice == :typed
74-
VarInfo(rng, model)
72+
DynamicPPL.typed_varinfo(rng, model)
7573
elseif varinfo_choice == :simple_namedtuple
7674
SimpleVarInfo{Float64}(model(rng))
7775
elseif varinfo_choice == :simple_dict

docs/Project.toml

+2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
[deps]
2+
AbstractPPL = "7a57a42e-76ec-4ea3-a279-07e840d6d9cf"
23
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
34
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
45
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
56
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
67
DocumenterMermaid = "a078cd44-4d9c-4618-b545-3ab9d77f9177"
8+
DynamicPPL = "366bfd00-2699-11ea-058f-f148b4cae6d8"
79
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"
810
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
911
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"

docs/make.jl

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ makedocs(;
2424
format=Documenter.HTML(; size_threshold=2^10 * 400),
2525
modules=[DynamicPPL, Base.get_extension(DynamicPPL, :DynamicPPLMCMCChainsExt)],
2626
pages=[
27-
"Home" => "index.md", "API" => "api.md", "Internals" => ["internals/varinfo.md"]
27+
"Home" => "index.md",
28+
"API" => "api.md",
29+
"Internals" => ["internals/varinfo.md", "internals/submodel_condition.md"],
2830
],
2931
checkdocs=:exports,
3032
doctest=false,

docs/src/api.md

+15-15
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ decondition
7878

7979
## Fixing and unfixing
8080

81-
We can also _fix_ a collection of variables in a [`Model`](@ref) to certain using [`fix`](@ref).
81+
We can also _fix_ a collection of variables in a [`Model`](@ref) to certain values using [`DynamicPPL.fix`](@ref).
8282

83-
This might seem quite similar to the aforementioned [`condition`](@ref) and its siblings,
83+
This is quite similar to the aforementioned [`condition`](@ref) and its siblings,
8484
but they are indeed different operations:
8585

8686
- `condition`ed variables are considered to be _observations_, and are thus
@@ -89,19 +89,19 @@ but they are indeed different operations:
8989
- `fix`ed variables are considered to be _constant_, and are thus not included
9090
in any log-probability computations.
9191

92-
The differences are more clearly spelled out in the docstring of [`fix`](@ref) below.
92+
The differences are more clearly spelled out in the docstring of [`DynamicPPL.fix`](@ref) below.
9393

9494
```@docs
95-
fix
95+
DynamicPPL.fix
9696
DynamicPPL.fixed
9797
```
9898

99-
The difference between [`fix`](@ref) and [`condition`](@ref) is described in the docstring of [`fix`](@ref) above.
99+
The difference between [`DynamicPPL.fix`](@ref) and [`DynamicPPL.condition`](@ref) is described in the docstring of [`DynamicPPL.fix`](@ref) above.
100100

101-
Similarly, we can [`unfix`](@ref) variables, i.e. return them to their original meaning:
101+
Similarly, we can revert this with [`DynamicPPL.unfix`](@ref), i.e. return the variables to their original meaning:
102102

103103
```@docs
104-
unfix
104+
DynamicPPL.unfix
105105
```
106106

107107
## Predicting
@@ -149,7 +149,7 @@ In the past, one would instead embed sub-models using [`@submodel`](@ref), which
149149
In the context of including models within models, it's also useful to prefix the variables in sub-models to avoid variable names clashing:
150150

151151
```@docs
152-
prefix
152+
DynamicPPL.prefix
153153
```
154154

155155
Under the hood, [`to_submodel`](@ref) makes use of the following method to indicate that the model it's wrapping is a model over its return-values rather than something else
@@ -212,6 +212,7 @@ To test and/or benchmark the performance of an AD backend on a model, DynamicPPL
212212
```@docs
213213
DynamicPPL.TestUtils.AD.run_ad
214214
DynamicPPL.TestUtils.AD.ADResult
215+
DynamicPPL.TestUtils.AD.ADIncorrectException
215216
```
216217

217218
## Demo models
@@ -300,18 +301,17 @@ AbstractVarInfo
300301

301302
But exactly how a [`AbstractVarInfo`](@ref) stores this information can vary.
302303

303-
For constructing the "default" typed and untyped varinfo types used in DynamicPPL (see [the section on varinfo design](@ref "Design of `VarInfo`") for more on this), we have the following two methods:
304+
#### `VarInfo`
304305

305306
```@docs
306-
DynamicPPL.untyped_varinfo
307-
DynamicPPL.typed_varinfo
307+
VarInfo
308308
```
309309

310-
#### `VarInfo`
311-
312310
```@docs
313-
VarInfo
314-
TypedVarInfo
311+
DynamicPPL.untyped_varinfo
312+
DynamicPPL.typed_varinfo
313+
DynamicPPL.untyped_vector_varinfo
314+
DynamicPPL.typed_vector_varinfo
315315
```
316316

317317
One main characteristic of [`VarInfo`](@ref) is that samples are transformed to unconstrained Euclidean space and stored in a linearized form, as described in the [main Turing documentation](https://turinglang.org/docs/developers/transforms/dynamicppl/).

0 commit comments

Comments
 (0)