Skip to content

Commit d52feec

Browse files
committed
Merge remote-tracking branch 'origin/breaking' into mhauru/custom-accumulators
2 parents 13da08a + c68f1bb commit d52feec

23 files changed

+1427
-255
lines changed

HISTORY.md

Lines changed: 82 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,25 @@
44

55
**Breaking changes**
66

7-
### VarInfo constructors
8-
9-
`VarInfo(vi::VarInfo, values)` has been removed. You can replace this directly with `unflatten(vi, values)` instead.
7+
### Submodels: conditioning
108

11-
The `metadata` argument to `VarInfo([rng, ]model[, sampler, context, metadata])` has been removed.
12-
If you were not using this argument (most likely), then there is no change needed.
13-
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).
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:
1411

15-
The `UntypedVarInfo` constructor and type is no longer exported.
16-
If you needed to construct one, you should now use `DynamicPPL.untyped_varinfo` instead.
17-
18-
The `TypedVarInfo` constructor and type is no longer exported.
19-
The _type_ has been replaced with `DynamicPPL.NTVarInfo`.
20-
The _constructor_ has been replaced with `DynamicPPL.typed_varinfo`.
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+
```
2121

22-
Note that the exact kind of VarInfo returned by `VarInfo(rng, model, ...)` is an implementation detail.
23-
Previously, it was guaranteed that this would always be a VarInfo whose metadata was a `NamedTuple` containing `Metadata` structs.
24-
Going forward, this is no longer the case, and you should only assume that the returned object obeys the `AbstractVarInfo` interface.
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.)
2524

26-
### VarName prefixing behaviour
25+
### Submodel prefixing
2726

2827
The way in which VarNames in submodels are prefixed has been changed.
2928
This is best explained through an example.
@@ -65,9 +64,62 @@ outer() | (@varname(var"a.x") => 1.0,)
6564
outer() | (a.x=1.0,)
6665
```
6766

68-
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.
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.
6990
(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.)
7091

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+
71123
**Other changes**
72124

73125
While these are technically breaking, they are only internal changes and do not affect the public API.
@@ -82,6 +134,19 @@ The reason for this change is that there were several flavours of VarInfo.
82134
Some, like `typed_varinfo`, were easy to construct because we had convenience methods for them; however, the others were more difficult.
83135
This change makes it easier to access different VarInfo types, and also makes it more explicit which one you are constructing.
84136

137+
## 0.35.9
138+
139+
Fixed the `isnan` check introduced in 0.35.7 for distributions which returned NamedTuple.
140+
141+
## 0.35.8
142+
143+
Added the `DynamicPPL.TestUtils.AD.run_ad` function to test the correctness and/or benchmark the performance of an automatic differentiation backend on DynamicPPL models.
144+
Please see [the docstring](https://turinglang.org/DynamicPPL.jl/api/#DynamicPPL.TestUtils.AD.run_ad) for more information.
145+
146+
## 0.35.7
147+
148+
`check_model_and_trace` now errors if any NaN's are encountered when evaluating the model.
149+
85150
## 0.35.6
86151

87152
Fixed the implementation of `.~`, such that running a model with it no longer requires DynamicPPL itself to be loaded.

Project.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
1010
BangBang = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
1111
Bijectors = "76274a88-744f-5084-9051-94815aaf08c4"
1212
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
13+
Chairmarks = "0ca39b1e-fe0b-4e98-acfc-b1656634c4de"
1314
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
1415
ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
1516
DifferentiationInterface = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63"
@@ -23,6 +24,7 @@ OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
2324
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
2425
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
2526
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
27+
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2628
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2729

2830
[weakdeps]
@@ -50,6 +52,7 @@ Accessors = "0.1"
5052
BangBang = "0.4.1"
5153
Bijectors = "0.13.18, 0.14, 0.15"
5254
ChainRulesCore = "1"
55+
Chairmarks = "1.3.1"
5356
Compat = "4"
5457
ConstructionBase = "1.5.4"
5558
DifferentiationInterface = "0.6.41"
@@ -69,5 +72,6 @@ OrderedCollections = "1"
6972
Printf = "1.10"
7073
Random = "1.6"
7174
Requires = "1"
75+
Statistics = "1"
7276
Test = "1.6"
7377
julia = "1.10"

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
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"

docs/make.jl

Lines changed: 3 additions & 1 deletion
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

Lines changed: 18 additions & 8 deletions
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
@@ -205,7 +205,17 @@ values_as_in_model
205205
NamedDist
206206
```
207207

208-
## Testing Utilities
208+
## AD testing and benchmarking utilities
209+
210+
To test and/or benchmark the performance of an AD backend on a model, DynamicPPL provides the following utilities:
211+
212+
```@docs
213+
DynamicPPL.TestUtils.AD.run_ad
214+
DynamicPPL.TestUtils.AD.ADResult
215+
DynamicPPL.TestUtils.AD.ADIncorrectException
216+
```
217+
218+
## Demo models
209219

210220
DynamicPPL provides several demo models and helpers for testing samplers in the `DynamicPPL.TestUtils` submodule.
211221

0 commit comments

Comments
 (0)