Skip to content

Commit 87bcf73

Browse files
authored
Turing v0.42 (#671)
* Update to v0.42 * Update command to reset Quarto Julia process in README * Update threadsafe docs for v0.42 * update FAQ * Update version in _quarto.yml * Update VI tutorial * lp -> logjoint * Fix VI interface * better code * lp -> logjoint * lp -> logjoint * fix shortcode * Fix external sampler interface * reword * fix meta shortcode * fix transforms * no NodeTrait * fix manual `Model` invocation * add clarifying comment * fix returned
1 parent c254968 commit 87bcf73

File tree

16 files changed

+364
-255
lines changed

16 files changed

+364
-255
lines changed

Manifest.toml

Lines changed: 60 additions & 70 deletions
Large diffs are not rendered by default.

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
5151
Turing = "fce5fe82-541a-59a6-adf8-730c64b5f9a0"
5252

5353
[compat]
54-
Turing = "0.41"
54+
Turing = "0.42"

README.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,15 @@ If you wish to speed up local rendering, there are two options available:
9595

9696
## Troubleshooting build issues
9797

98-
As described in the [Quarto docs](https://quarto.org/docs/computations/julia.html#using-the-julia-engine), Quarto's Julia engine uses a worker process behind the scenes.
98+
Quarto's Julia engine uses a separate worker process behind the scenes.
9999
Sometimes this can result in issues with old package code not being unloaded (e.g. when package versions are upgraded).
100-
If you find that Quarto's execution is failing with errors that aren't reproducible via a normal REPL, try adding the `--execute-daemon-restart` flag to the `quarto render` command:
100+
If you find that Quarto's execution is failing with errors that aren't reproducible via a normal REPL, try running:
101101

102102
```bash
103-
quarto render /path/to/index.qmd --execute-daemon-restart
103+
quarto call engine julia kill
104104
```
105105

106-
And also, kill any stray Quarto processes that are still running (sometimes it keeps running in the background):
107-
108-
```bash
109-
pkill -9 -f quarto
110-
```
106+
before rerunning the build (see [the Quarto docs](https://quarto.org/docs/computations/julia.html#quarto-call-engine-julia-commands) for more information).
111107

112108
## Licence
113109

_quarto.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ website:
4343
href: https://turinglang.org/team/
4444
right:
4545
# Current version
46-
- text: "v0.41"
46+
- text: "v0.42"
4747
menu:
4848
- text: Changelog
4949
href: https://turinglang.org/docs/changelog.html

developers/compiler/model-manual/index.qmd

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ function gdemo2(model, varinfo, x)
5454
# value and the updated varinfo.
5555
return nothing, varinfo
5656
end
57-
gdemo2(x) = DynamicPPL.Model(gdemo2, (; x))
57+
58+
# The `false` type parameter here indicates that this model does not need
59+
# threadsafe evaluation (see the threadsafe evaluation page for details)
60+
gdemo2(x) = DynamicPPL.Model{false}(gdemo2, (; x))
5861
5962
# Instantiate a Model object with our data variables.
6063
model2 = gdemo2([1.5, 2.0])
@@ -66,4 +69,4 @@ We can sample from this model in the same way:
6669
chain = sample(model2, NUTS(), 1000; progress=false)
6770
```
6871

69-
The subsequent pages in this section will show how the `@model` macro does this behind-the-scenes.
72+
The subsequent pages in this section will show how the `@model` macro does this behind-the-scenes.

developers/contexts/submodel-condition/index.qmd

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -265,18 +265,11 @@ We should like `myprefix(big_ctx, @varname(x))` to return `@varname(a.b.x)`.
265265
Consider the following naive implementation, which mirrors a lot of code in the tilde-pipeline:
266266

267267
```{julia}
268-
using DynamicPPL: NodeTrait, IsLeaf, IsParent, childcontext, AbstractContext
268+
using DynamicPPL: childcontext, AbstractContext, AbstractParentContext
269269
using AbstractPPL: AbstractPPL
270270
271-
function myprefix(ctx::DynamicPPL.AbstractContext, vn::VarName)
272-
return myprefix(NodeTrait(ctx), ctx, vn)
273-
end
274-
function myprefix(::IsLeaf, ::AbstractContext, vn::VarName)
275-
return vn
276-
end
277-
function myprefix(::IsParent, ctx::AbstractContext, vn::VarName)
278-
return myprefix(childcontext(ctx), vn)
279-
end
271+
myprefix(::AbstractContext, vn::VarName) = vn
272+
myprefix(ctx::AbstractParentContext, vn::VarName) = myprefix(childcontext(ctx), vn)
280273
function myprefix(ctx::DynamicPPL.PrefixContext, vn::VarName)
281274
# The functionality to actually manipulate the VarNames is in AbstractPPL
282275
new_vn = AbstractPPL.prefix(vn, ctx.vn_prefix)

developers/inference/abstractmcmc-interface/index.qmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,4 +320,4 @@ It looks like we're extremely close to our true parameters of `Normal(5,3)`, tho
320320

321321
## Conclusion
322322

323-
We've seen how to implement the sampling interface for general projects. Turing's interface methods are ever-evolving, so please open an issue at [AbstractMCMC](https://github.com/TuringLang/AbstractMCMC.jl) with feature requests or problems.
323+
We've seen how to implement the sampling interface for general projects. Turing's interface methods are ever-evolving, so please open an issue at [AbstractMCMC](https://github.com/TuringLang/AbstractMCMC.jl) with feature requests or problems.

developers/inference/implementing-samplers/index.qmd

Lines changed: 82 additions & 40 deletions
Large diffs are not rendered by default.

developers/models/varinfo-overview/index.qmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ If you use it, you must pay close attention to correctness:**
233233

234234
1. For models with multiple variables, the order in which these variables occur in the vector is not obvious. The short answer is that it depends on the order in which the variables are added to the VarInfo during its initialisation. If you have models where the order of variables can vary from one execution to another, then `unflatten` can easily lead to incorrect results.
235235

236-
2. The meaning of the values passed in will generally depend on whether the VarInfo is linked or not (see the [Variable Transformations page]({{< meta developers/transforms/dynamicppl >}}) for more information about linked VarInfos). You must make sure that the values passed in are consistent with the link status of the VarInfo. In contrast, `InitFromParams` always uses unlinked values.
236+
2. The meaning of the values passed in will generally depend on whether the VarInfo is linked or not (see the [Variable Transformations page]({{< meta dev-transforms-dynamicppl >}}) for more information about linked VarInfos). You must make sure that the values passed in are consistent with the link status of the VarInfo. In contrast, `InitFromParams` always uses unlinked values.
237237

238238
3. While `unflatten` modifies the parameter values stored in the VarInfo, it does not modify any other information, such as log probabilities. Thus, after calling `unflatten`, your VarInfo will be in an inconsistent state, and you should not attempt to read any other information from it until you have called `evaluate!!` again (which recomputes e.g. log probabilities).
239239

developers/transforms/dynamicppl/index.qmd

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -126,50 +126,24 @@ This sequence of events is summed up in the following diagram, where `f(..., arg
126126
In the final part of this article, we will take a more in-depth look at the internal DynamicPPL machinery that allows us to convert between representations and obtain the correct probability densities.
127127
Before that, though, we will take a quick high-level look at how the HMC sampler in Turing.jl uses the functions introduced so far.
128128

129-
## Case study: HMC in Turing.jl
129+
## HMC in Turing.jl
130130

131131
While DynamicPPL provides the _functionality_ for transforming variables, the transformation itself happens at an even higher level, i.e. in the sampler itself.
132132
The HMC sampler in Turing.jl is in [this file](https://github.com/TuringLang/Turing.jl/blob/5b24cebe773922e0f3d5c4cb7f53162eb758b04d/src/mcmc/hmc.jl).
133-
In the first step of sampling, it calls `link` on the sampler.
134-
This transformation is preserved throughout the sampling process, meaning that `is_transformed()` always returns true.
135-
136-
We can observe this by inserting print statements into the model.
137-
Here, `__varinfo__` is the internal symbol for the `VarInfo` object used in model evaluation:
138-
139-
```{julia}
140-
setprogress!(false)
141-
142-
@model function demo2()
143-
x ~ LogNormal()
144-
if x isa AbstractFloat
145-
println("-----------")
146-
println("model repn: $(DynamicPPL.getindex(__varinfo__, @varname(x)))")
147-
println("internal repn: $(DynamicPPL.getindex_internal(__varinfo__, @varname(x)))")
148-
println("is_transformed: $(is_transformed(__varinfo__, @varname(x)))")
149-
end
150-
end
151-
152-
sample(demo2(), HMC(0.1, 3), 3);
153-
```
154-
155-
156-
(Here, the check on `if x isa AbstractFloat` prevents the printing from occurring during computation of the derivative.)
157-
You can see that during the three sampling steps, `is_transformed` is always kept as `true`.
158-
159-
::: {.callout-note}
160-
The first two model evaluations where `is_transformed` is `false` occur prior to the actual sampling.
161-
One occurs when the model is checked for correctness (using [`DynamicPPL.check_model_and_trace`](https://github.com/TuringLang/DynamicPPL.jl/blob/ba490bf362653e1aaefe298364fe3379b60660d3/src/debug_utils.jl#L582-L612)).
162-
The second occurs because the model is evaluated once to generate a set of initial parameters inside [DynamicPPL's implementation of `AbstractMCMC.step`](https://github.com/TuringLang/DynamicPPL.jl/blob/ba490bf362653e1aaefe298364fe3379b60660d3/src/sampler.jl#L98-L117).
163-
Both of these steps occur with all samplers in Turing.jl, so are not specific to the HMC example shown here.
164-
:::
165133

134+
In the first step of sampling, it calls `link` on the sampler.
166135
What this means is that from the perspective of the HMC sampler, it _never_ sees the constrained variable: it always thinks that it is sampling from an unconstrained distribution.
167136

168137
The biggest prerequisite for this to work correctly is that the potential energy term in the Hamiltonian—or in other words, the model log density—must be programmed correctly to include the Jacobian term.
169138
This is exactly the same as how we had to make sure to define `logq(y)` correctly in the toy HMC example above.
170139

171-
Within Turing.jl, this is correctly handled because a statement like `x ~ LogNormal()` in the model definition above is translated into `assume(LogNormal(), @varname(x), __varinfo__)`, defined [here](https://github.com/TuringLang/DynamicPPL.jl/blob/ba490bf362653e1aaefe298364fe3379b60660d3/src/context_implementations.jl#L225-L229).
172-
If you follow the trail of function calls, you can verify that the `assume` function does indeed check for the presence of the `is_transformed` flag and adds the Jacobian term accordingly.
140+
Within Turing.jl, this is correctly handled by calling
141+
142+
```julia
143+
x, inv_logjac = with_logabsdet_jacobian(y, inverse_transform)
144+
```
145+
146+
and then passing `inv_logjac` to DynamicPPL's `LogJacobianAccumulator`.
173147

174148
## A deeper dive into DynamicPPL's internal machinery
175149

@@ -415,4 +389,4 @@ In this chapter of the Turing docs, we've looked at:
415389
- the higher-level usage of transforms in DynamicPPL and Turing.
416390

417391
This will hopefully have equipped you with a better understanding of how constrained variables are handled in the Turing framework.
418-
With this knowledge, you should especially find it easier to navigate DynamicPPL's `VarInfo` type, which forms the backbone of model evaluation.
392+
With this knowledge, you should especially find it easier to navigate DynamicPPL's `VarInfo` type, which forms the backbone of model evaluation.

0 commit comments

Comments
 (0)