Skip to content

Commit d3d32e4

Browse files
penelopeysmmhauru
andauthored
InitContext, part 5 - Remove SamplingContext, SampleFrom{Prior,Uniform}, {tilde_,}assume (#985)
* Remove `SamplingContext` for good * Remove `tilde_assume` as well * Split up tilde_observe!! for Distribution / Submodel * Tidy up tilde-pipeline methods and docstrings * Fix tests * fix ambiguity * Add changelog * Update HISTORY.md Co-authored-by: Markus Hauru <[email protected]> --------- Co-authored-by: Markus Hauru <[email protected]>
1 parent 0114e64 commit d3d32e4

20 files changed

+205
-490
lines changed

HISTORY.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,66 @@
22

33
## 0.38.0
44

5-
The `varname_leaves` and `varname_and_value_leaves` functions have been moved to AbstractPPL.jl.
6-
Their behaviour is otherwise identical.
5+
**Breaking changes**
6+
7+
### Introduction of `InitContext`
8+
9+
DynamicPPL 0.38 introduces a new evaluation context, `InitContext`.
10+
It is used to generate fresh values for random variables in a model.
11+
12+
Evaluation contexts are stored inside a `DynamicPPL.Model` object, and control what happens with tilde-statements when a model is run.
13+
The two major leaf (basic) contexts are `DefaultContext` and, now, `InitContext`.
14+
`DefaultContext` is the default context, and it simply uses the values that are already stored in the `VarInfo` object passed to the model evaluation function.
15+
On the other hand, `InitContext` ignores values in the VarInfo object and inserts new values obtained from a specified source.
16+
(It follows also that the VarInfo being used may be empty, which means that `InitContext` is now also the way to obtain a fresh VarInfo for a model.)
17+
18+
DynamicPPL 0.38 provides three flavours of _initialisation strategies_, which are specified as the second argument to `InitContext`:
19+
20+
- `InitContext(rng, InitFromPrior())`: New values are sampled from the prior distribution (on the right-hand side of the tilde).
21+
- `InitContext(rng, InitFromUniform(a, b))`: New values are sampled uniformly from the interval `[a, b]`, and then invlinked to the support of the distribution on the right-hand side of the tilde.
22+
- `InitContext(rng, InitFromParams(p, fallback))`: New values are obtained by indexing into the `p` object, which can be a `NamedTuple` or `Dict{<:VarName}`. If a variable is not found in `p`, then the `fallback` strategy is used, which is simply another of these strategies. In particular, `InitFromParams` enables the case where different variables are to be initialised from different sources.
23+
24+
(It is possible to define your own initialisation strategy; users who wish to do so are referred to the DynamicPPL API documentation and source code.)
25+
26+
**The main impact on the upcoming Turing.jl release** is that, instead of providing initial values for sampling, the user will be expected to provide an initialisation strategy instead.
27+
This is a more flexible approach, and not only solves a number of pre-existing issues with initialisation of Turing models, but also improves the clarity of user code.
28+
In particular:
29+
30+
- When providing a set of fixed parameters (i.e. `InitFromParams(p)`), `p` must now either be a NamedTuple or a Dict. Previously Vectors were allowed, which is error-prone because the ordering of variables in a VarInfo is not obvious.
31+
- The parameters in `p` must now always be provided in unlinked space (i.e., in the space of the distribution on the right-hand side of the tilde). Previously, whether a parameter was expected to be in linked or unlinked space depended on whether the VarInfo was linked or not, which was confusing.
32+
33+
### Removal of `SamplingContext`
34+
35+
For developers working on DynamicPPL, `InitContext` now completely replaces what used to be `SamplingContext`, `SampleFromPrior`, and `SampleFromUniform`.
36+
Evaluating a model with `SamplingContext(SampleFromPrior())` (e.g. with `DynamicPPL.evaluate_and_sample!!(model, VarInfo(), SampleFromPrior())` has a direct one-to-one replacement in `DynamicPPL.init!!(model, VarInfo(), InitFromPrior())`.
37+
Please see the docstring of `init!!` for more details.
38+
Likewise `SampleFromUniform()` can be replaced with `InitFromUniform()`.
39+
`InitFromParams()` provides new functionality which was previously implemented in the roundabout way of manipulating the VarInfo (e.g. using `unflatten`, or even more hackily by directly modifying values in the VarInfo), and then evaluating using `DefaultContext`.
40+
41+
The main change that this is likely to create is for those who are implementing samplers or inference algorithms.
42+
The exact way in which this happens will be detailed in the Turing.jl changelog when a new release is made.
43+
Broadly speaking, though, `SamplingContext(MySampler())` will be removed so if your sampler needs custom behaviour with the tilde-pipeline you will likely have to define your own context.
44+
45+
### Simplification of the tilde-pipeline
46+
47+
There are now only two functions in the tilde-pipeline that need to be overloaded to change the behaviour of tilde-statements, namely, `tilde_assume!!` and `tilde_observe!!`.
48+
Other functions such as `tilde_assume` and `assume` (and their `observe` counterparts) have been removed.
49+
50+
Note that this was effectively already the case in DynamicPPL 0.37 (where they were just wrappers around each other).
51+
The separation of these functions was primarily implemented to avoid performing extra work where unneeded (e.g. to not calculate the log-likelihood when `PriorContext` was being used). This functionality has since been replaced with accumulators (see the 0.37 changelog for more details).
52+
53+
**Other changes**
54+
55+
### Reimplementation of functions using `InitContext`
56+
57+
A number of functions have been reimplemented and unified with the help of `InitContext`.
58+
In particular, this release brings substantial performance improvements for `returned` and `predict`.
59+
Their APIs are the same.
60+
61+
### Upstreaming of VarName functionality
62+
63+
The implementation of the `varname_leaves` and `varname_and_value_leaves` functions have been moved to AbstractPPL.jl.
64+
Their behaviour is otherwise identical, and they are still accessible from the DynamicPPL module (though still not exported).
765

866
## 0.37.3
967

docs/src/api.md

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Part of the API of DynamicPPL is defined in the more lightweight interface packa
88

99
A core component of DynamicPPL is the [`@model`](@ref) macro.
1010
It can be used to define probabilistic models in an intuitive way by specifying random variables and their distributions with `~` statements.
11-
These statements are rewritten by `@model` as calls of [internal functions](@ref model_internal) for sampling the variables and computing their log densities.
11+
These statements are rewritten by `@model` as calls of internal functions for sampling the variables and computing their log densities.
1212

1313
```@docs
1414
@model
@@ -344,6 +344,13 @@ Base.empty!
344344
SimpleVarInfo
345345
```
346346

347+
### Tilde-pipeline
348+
349+
```@docs
350+
tilde_assume!!
351+
tilde_observe!!
352+
```
353+
347354
### Accumulators
348355

349356
The subtypes of [`AbstractVarInfo`](@ref) store the cumulative log prior and log likelihood, and sometimes other variables that change during executing, in what are called accumulators.
@@ -447,12 +454,12 @@ AbstractPPL.evaluate!!
447454

448455
This method mutates the `varinfo` used for execution.
449456
By default, it does not perform any actual sampling: it only evaluates the model using the values of the variables that are already in the `varinfo`.
457+
If you wish to sample new values, see the section on [VarInfo initialisation](#VarInfo-initialisation) just below this.
450458

451459
The behaviour of a model execution can be changed with evaluation contexts, which are a field of the model.
452460
Contexts are subtypes of `AbstractPPL.AbstractContext`.
453461

454462
```@docs
455-
SamplingContext
456463
DefaultContext
457464
PrefixContext
458465
ConditionContext
@@ -486,15 +493,7 @@ DynamicPPL.init
486493

487494
### Samplers
488495

489-
In DynamicPPL two samplers are defined that are used to initialize unobserved random variables:
490-
[`SampleFromPrior`](@ref) which samples from the prior distribution, and [`SampleFromUniform`](@ref) which samples from a uniform distribution.
491-
492-
```@docs
493-
SampleFromPrior
494-
SampleFromUniform
495-
```
496-
497-
Additionally, a generic sampler for inference is implemented.
496+
In DynamicPPL a generic sampler for inference is implemented.
498497

499498
```@docs
500499
Sampler
@@ -520,9 +519,3 @@ There is also the _experimental_ [`DynamicPPL.Experimental.determine_suitable_va
520519
DynamicPPL.Experimental.determine_suitable_varinfo
521520
DynamicPPL.Experimental.is_suitable_varinfo
522521
```
523-
524-
### [Model-Internal Functions](@id model_internal)
525-
526-
```@docs
527-
tilde_assume
528-
```

ext/DynamicPPLEnzymeCoreExt.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ else
88
using ..EnzymeCore
99
end
1010

11-
@inline EnzymeCore.EnzymeRules.inactive_type(::Type{<:DynamicPPL.SamplingContext}) = true
12-
1311
# Mark istrans as having 0 derivative. The `nothing` return value is not significant, Enzyme
1412
# only checks whether such a method exists, and never runs it.
1513
@inline EnzymeCore.EnzymeRules.inactive(::typeof(DynamicPPL.istrans), args...) = nothing

src/DynamicPPL.jl

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,16 @@ export AbstractVarInfo,
9696
values_as_in_model,
9797
# Samplers
9898
Sampler,
99-
SampleFromPrior,
100-
SampleFromUniform,
10199
# LogDensityFunction
102100
LogDensityFunction,
103101
# Contexts
104102
contextualize,
105-
SamplingContext,
106103
DefaultContext,
107104
PrefixContext,
108105
ConditionContext,
109-
assume,
110-
tilde_assume,
106+
# Tilde pipeline
107+
tilde_assume!!,
108+
tilde_observe!!,
111109
# Initialisation
112110
InitContext,
113111
AbstractInitStrategy,

0 commit comments

Comments
 (0)