|  | 
| 1 | 1 | # DynamicPPL Changelog | 
| 2 | 2 | 
 | 
|  | 3 | +## 0.38.0 | 
|  | 4 | + | 
|  | 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 | +#### Removal of `DynamicPPL.Sampler` | 
|  | 46 | + | 
|  | 47 | +`DynamicPPL.Sampler` and **all associated interface functions** have also been removed entirely. | 
|  | 48 | +If you were using these, the corresponding replacements are: | 
|  | 49 | + | 
|  | 50 | +  - `DynamicPPL.Sampler(S)`: just don't wrap `S`; but make sure `S` subtypes `AbstractMCMC.AbstractSampler` | 
|  | 51 | +  - `DynamicPPL.initialstep`: directly implement `AbstractMCMC.step` and `AbstractMCMC.step_warmup` as per the AbstractMCMC interface | 
|  | 52 | +  - `DynamicPPL.loadstate`: `Turing.loadstate` (will be introduced in the next version) | 
|  | 53 | +  - `DynamicPPL.default_chain_type`: removed, just use the `chain_type` keyword argument directly | 
|  | 54 | +  - `DynamicPPL.initialsampler`: `Turing.Inference.init_strategy` (will be introduced in the next version; note that this function must return an `AbstractInitStrategy`, see above for explanation) | 
|  | 55 | +  - `DynamicPPL.default_varinfo`: `Turing.Inference.default_varinfo` (will be introduced in the next version) | 
|  | 56 | +  - `DynamicPPL.TestUtils.test_sampler` and related methods: removed, please implement your own testing utilities as needed | 
|  | 57 | + | 
|  | 58 | +#### Simplification of the tilde-pipeline | 
|  | 59 | + | 
|  | 60 | +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!!`. | 
|  | 61 | +Other functions such as `tilde_assume` and `assume` (and their `observe` counterparts) have been removed. | 
|  | 62 | + | 
|  | 63 | +Note that this was effectively already the case in DynamicPPL 0.37 (where they were just wrappers around each other). | 
|  | 64 | +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). | 
|  | 65 | + | 
|  | 66 | +#### Removal of the `"del"` flag | 
|  | 67 | + | 
|  | 68 | +Previously `VarInfo` (or more correctly, the `Metadata` object within a `VarInfo`), had a flag called `"del"` for all variables. If it was set to `true` the variable was to be overwritten with a new value at the next evaluation. The new `InitContext` and related changes above make this flag unnecessary, and it has been removed. | 
|  | 69 | + | 
|  | 70 | +The only flag other than `"del"` that `Metadata` ever used was `"trans"`. Thus the generic functions `set_flag!`, `unset_flag!` and `is_flagged!` have also been removed in favour of more specific ones. We've also used this opportunity to name the `"trans"` flag and the corresponding `istrans` function to be more explicit. The new, exported interface consists of the `is_transformed` and `set_transformed!!` functions. | 
|  | 71 | + | 
|  | 72 | +#### Removal of `resume_from` | 
|  | 73 | + | 
|  | 74 | +The `resume_from=chn` keyword argument to `sample` has been removed; please use the `initial_state` argument instead. | 
|  | 75 | +`loadstate` will be exported from Turing in the next release of Turing. | 
|  | 76 | + | 
|  | 77 | +#### Change of output type for `pointwise_logdensities` | 
|  | 78 | + | 
|  | 79 | +The functions `pointwise_prior_logdensities`, `pointwise_logdensities`, and `pointwise_loglikelihoods` when called on `MCMCChains.Chains` objects, now return new `MCMCChains.Chains` objects by default, instead of dictionaries of matrices. | 
|  | 80 | + | 
|  | 81 | +If you want the old behaviour, you can pass `OrderedDict` as the third argument, i.e., `pointwise_logdensities(model, chain, OrderedDict)`. | 
|  | 82 | + | 
|  | 83 | +### Other changes | 
|  | 84 | + | 
|  | 85 | +#### `predict(model, chain; include_all)` | 
|  | 86 | + | 
|  | 87 | +The `include_all` keyword argument for `predict` now works even when no RNG is specified (previously it would only work when an RNG was explicitly passed). | 
|  | 88 | + | 
|  | 89 | +#### `DynamicPPL.setleafcontext(model, context)` | 
|  | 90 | + | 
|  | 91 | +This convenience method has been added to quickly modify the leaf context of a model. | 
|  | 92 | + | 
|  | 93 | +#### Reimplementation of functions using `InitContext` | 
|  | 94 | + | 
|  | 95 | +A number of functions have been reimplemented and unified with the help of `InitContext`. | 
|  | 96 | +In particular, this release brings substantial performance improvements for `returned` and `predict`. | 
|  | 97 | +Their APIs are the same. | 
|  | 98 | + | 
|  | 99 | +#### Upstreaming of VarName functionality | 
|  | 100 | + | 
|  | 101 | +The implementation of the `varname_leaves` and `varname_and_value_leaves` functions have been moved to AbstractPPL.jl. | 
|  | 102 | +Their behaviour is otherwise identical, and they are still accessible from the DynamicPPL module (though still not exported). | 
|  | 103 | + | 
| 3 | 104 | ## 0.37.5 | 
| 4 | 105 | 
 | 
| 5 | 106 | A minor optimisation for Enzyme AD on DynamicPPL models. | 
|  | 
0 commit comments