Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
176 commits
Select commit Hold shift + click to select a range
8c3d30f
v0.39
penelopeysm Oct 21, 2025
262d732
Merge remote-tracking branch 'origin/main' into breaking
mhauru Oct 22, 2025
77af4eb
Merge branch 'main' into breaking
penelopeysm Oct 28, 2025
c57de02
Merge remote-tracking branch 'origin/main' into breaking
mhauru Oct 31, 2025
7300c22
Update DPPL compats for benchmarks and docs
mhauru Oct 31, 2025
79150ba
remove merge conflict markers
penelopeysm Nov 4, 2025
6dc7c02
Merge remote-tracking branch 'origin/main' into breaking
mhauru Nov 5, 2025
2ca96cc
Merge branch 'main' into breaking
penelopeysm Nov 5, 2025
a8eb2e7
Merge branch 'main' into breaking
penelopeysm Nov 11, 2025
4ca9528
Remove `NodeTrait` (#1133)
penelopeysm Nov 11, 2025
535ce4f
FastLDF / InitContext unified (#1132)
penelopeysm Nov 13, 2025
9624103
implement `LogDensityProblems.dimension`
penelopeysm Nov 14, 2025
ce80713
forgot about capabilities...
penelopeysm Nov 14, 2025
1d21728
Merge branch 'main' into breaking
penelopeysm Nov 18, 2025
c4cec0b
Merge branch 'main' into breaking
penelopeysm Nov 18, 2025
8553e40
use interpolation in run_ad
penelopeysm Nov 18, 2025
3cd8d34
Improvements to benchmark outputs (#1146)
penelopeysm Nov 18, 2025
eab7131
Add VarNamedTuple, tests, and WIP docs
mhauru Nov 19, 2025
0c7825b
Add comparisons and merge
mhauru Nov 20, 2025
15d5a8a
Start using VNT in FastLDF
mhauru Nov 20, 2025
871eb9f
Move _compose_no_identity to utils.jl
mhauru Nov 20, 2025
4a11560
Allow generation of `ParamsWithStats` from `FastLDF` plus parameters,…
penelopeysm Nov 22, 2025
766f663
Make FastLDF the default (#1139)
penelopeysm Nov 25, 2025
c1b935b
Minor refactor
mhauru Nov 25, 2025
262a6f9
Remove IndexDict
mhauru Nov 25, 2025
abea087
Remove make_leaf as a field
mhauru Nov 25, 2025
5900f69
Document, refactor, and fix PartialArray
mhauru Nov 25, 2025
8f17dcf
Make PartialArray more type stable.
mhauru Nov 25, 2025
8547e25
Implement `predict`, `returned`, `logjoint`, ... with `OnlyAccsVarInf…
penelopeysm Nov 25, 2025
04b3383
Fixes and improvements to VNT
mhauru Nov 25, 2025
59c4dcb
Proper printing and constructors
mhauru Nov 25, 2025
381b1dd
Fix PartialArray printing
mhauru Nov 25, 2025
88db66d
Update the design doc
mhauru Nov 25, 2025
a6d56a2
Improve FastLDF type stability when all parameters are linked or unli…
penelopeysm Nov 27, 2025
018d14f
Merge remote-tracking branch 'origin/breaking' into mhauru/vnt-for-fa…
mhauru Nov 27, 2025
eca65d5
Fix a test
mhauru Nov 27, 2025
5e27a05
Fix copy and show
mhauru Nov 27, 2025
050b8c5
Add test_invariants to VNT tests
mhauru Nov 27, 2025
f5616df
Improve VNT internal docs
mhauru Nov 27, 2025
ec5dc8f
Polish VNT
mhauru Nov 27, 2025
3ca36c4
Make VNT merge type stable. Simplify printing, improve tests.
mhauru Nov 27, 2025
59f67fd
Add VNT too API docs
mhauru Nov 27, 2025
9aba468
Fix doctests
mhauru Nov 27, 2025
0b4c772
Clean up tests a bit
mhauru Nov 27, 2025
38662a8
Fix API docs
mhauru Nov 27, 2025
e41afca
Fix a bug and a docstring
mhauru Nov 27, 2025
8c50bbb
Apply suggestions from code review
mhauru Nov 28, 2025
cae8864
Fix VNT docs
mhauru Nov 28, 2025
c27f5e0
Make threadsafe evaluation opt-in (#1151)
penelopeysm Dec 1, 2025
993cc5b
Merge remote-tracking branch 'origin/main' into breaking
penelopeysm Dec 1, 2025
54ae7e3
Standardise `:lp` -> `:logjoint` (#1161)
penelopeysm Dec 1, 2025
1bb97ae
Bump minor version to 0.40
mhauru Dec 3, 2025
6012b11
Merge branch 'tmp2' into mhauru/vnt-for-fastldf
mhauru Dec 3, 2025
f114e40
Merge commit 'ee863d6' into mhauru/vnt-for-fastldf
mhauru Dec 3, 2025
bccfdf0
Merge branch 'breaking' into mhauru/vnt-for-fastldf
mhauru Dec 3, 2025
384e3ac
Apply suggestions from code review
mhauru Dec 3, 2025
9d61a54
Add a microoptimisation
mhauru Dec 3, 2025
8c8e39f
Improve docstrings
mhauru Dec 3, 2025
c818bf8
Simplify use of QuoteNodes
mhauru Dec 3, 2025
3c02da4
Improve equality tests
mhauru Dec 11, 2025
35c3e20
ArrayLikeBlock WIP
mhauru Dec 11, 2025
4253e9b
ArrayLikeBlock WIP2
mhauru Dec 12, 2025
5cb3916
Improve type stability of ArrayLikeBlock stuff
mhauru Dec 12, 2025
a96bb44
Test more invariants
mhauru Dec 15, 2025
a8014e6
Actually run VNT tests
mhauru Dec 15, 2025
cfc6041
Implement show for ArrayLikeBlock
mhauru Dec 15, 2025
e198fbb
Change keys on VNT to return an array
mhauru Dec 15, 2025
b77b0af
Fix keys and some tests for PartialArray
mhauru Dec 15, 2025
633e920
Improve type stability
mhauru Dec 15, 2025
222334a
Fix keys for PartialArray
mhauru Dec 15, 2025
d22face
More ArrayLikeBlock tests
mhauru Dec 15, 2025
4cb49e1
Add docstrings
mhauru Dec 15, 2025
420a6b2
Remove redundant code, improve documentation
mhauru Dec 15, 2025
62e0da8
Merge remote-tracking branch 'origin/main' into breaking
mhauru Dec 15, 2025
44be19d
Merge branch 'breaking' into mhauru/vnt-for-fastldf
mhauru Dec 15, 2025
d2f58d7
Merge branch 'mhauru/vnt-for-fastldf' into mhauru/arraylikeblock
mhauru Dec 15, 2025
ce9da19
Add Base.size(::RangeAndLinked)
mhauru Dec 15, 2025
4eb33e9
Fix issues with RangeAndLinked and VNT
mhauru Dec 15, 2025
51b399a
Write more design doc for ArrayLikeBlocks
mhauru Dec 15, 2025
57fd11a
Make VNT support concretized slices
mhauru Dec 16, 2025
7bdce5c
Start the VNT HISTORY.md entry
mhauru Dec 16, 2025
9992051
Skip a type stability test on 1.10
mhauru Dec 16, 2025
753ca81
Fix test_skip
mhauru Dec 16, 2025
34c42af
Change Base.keys on PartialArrays to be more type stable
mhauru Dec 1, 2025
262e303
Implement Base.values for VNT
mhauru Dec 1, 2025
1f2cd8b
Implement isempty and empty for VNT
mhauru Dec 1, 2025
1debab1
Use VNT in VAIMAcc
mhauru Dec 1, 2025
1db910c
WIP implementation of empty!! for VNT
mhauru Dec 3, 2025
b02d014
Make to_samples use VNT and fix related tests
mhauru Dec 17, 2025
ea807fc
Add hasvalue and getvalue to VNT
mhauru Dec 17, 2025
f2d0c33
Improve keys and values for VNT
mhauru Dec 17, 2025
086fd7c
Add length and _to_dense_array for VNT
mhauru Dec 17, 2025
e98b0e8
Fix empty and friends for VNT, add tests
mhauru Dec 17, 2025
07bf11f
Add tests of VNT densification
mhauru Dec 17, 2025
852609d
Fix some comments
mhauru Dec 17, 2025
4a585ad
Apply polish
mhauru Dec 17, 2025
34ad663
Fix and improve map!! and apply!!
mhauru Dec 18, 2025
dc6291d
mapreduce and nested PartialArrays
mhauru Dec 18, 2025
20ed575
Test invariants more
mhauru Dec 18, 2025
477b715
Work-in-progress VNTVarInfo
mhauru Dec 18, 2025
7aa6013
Fix a bug in link
mhauru Dec 18, 2025
d9e5405
Mark a test as broken on 1.10
mhauru Dec 19, 2025
05dd3af
Fix hasvalue and getvalue for VNT
mhauru Dec 19, 2025
267c554
Trivial bug fix
mhauru Dec 19, 2025
6a4c148
Merge branch 'mhauru/vnt-concretized-slices' into mhauru/vnt-for-vaimacc
mhauru Dec 19, 2025
76ac5b6
Use skip rather than broken for an inference test
mhauru Dec 19, 2025
c917266
Merge branch 'mhauru/vnt-concretized-slices' into mhauru/vnt-for-vaimacc
mhauru Dec 19, 2025
9ae56ab
Merge branch 'mhauru/vnt-for-vaimacc' into mhauru/vnt-for-varinfo
mhauru Dec 19, 2025
f3f866b
Merge branch 'main' into breaking
penelopeysm Jan 2, 2026
0c50bd7
Fix a docs typo
mhauru Jan 6, 2026
6b211b1
Use floatmin in test_utils
mhauru Jan 6, 2026
57fd84b
Narrow a skip clause
mhauru Jan 6, 2026
345b605
Use vnt_size instead of Base.size
mhauru Jan 6, 2026
4f12e99
Bugfix
mhauru Jan 6, 2026
60b2399
Style improvements
mhauru Jan 6, 2026
e603229
Remove to_dict on VNT
mhauru Jan 6, 2026
21ba31d
Remove unneeded Union
penelopeysm Jan 6, 2026
bb22bc3
Merge branch 'mhauru/vnt-for-vaimacc' into mhauru/vnt-for-fastldf
mhauru Jan 7, 2026
cacd426
Add vnt_size docstring to API docs
mhauru Jan 7, 2026
a848290
Merge branch 'mhauru/vnt-vntsize' into mhauru/vnt-for-fastldf
mhauru Jan 7, 2026
bdeeb4a
Update map!! to operate on pairs
mhauru Jan 8, 2026
5498d82
Split map!! into map_pairs!! and map_values!!, fix some bugs
mhauru Jan 8, 2026
81be716
Make mapreduce operate on pairs
mhauru Jan 8, 2026
37f4adf
Implement keys and values using mapreduce
mhauru Jan 8, 2026
fc29cc6
Add more VNT constructors
mhauru Jan 9, 2026
c6d0677
Add VNT subset
mhauru Jan 9, 2026
c18258c
Make _compose_no_identity handle typed_identity too
mhauru Jan 9, 2026
b91e6ff
Myriad improvements to VNTVarInfo, overhaul varinfo.jl tests to use V…
mhauru Jan 9, 2026
4b1a8f5
Merge remote-tracking branch 'origin/mhauru/vnt-for-fastldf' into mha…
mhauru Jan 9, 2026
8018f45
Fix a couple of ArrayLikeBlock bugs
mhauru Jan 9, 2026
1cbcda7
Fix PartialArray map bug
mhauru Jan 9, 2026
573cd5a
In VNTVarInfo, handle variables with varying dimensions correctly
mhauru Jan 9, 2026
c353cbc
Fix two small bugs
mhauru Jan 9, 2026
a36bb15
Allow nested PartialArrays with ArrayLikeBlocks
mhauru Jan 9, 2026
bf05554
Stop testing for NamedDist with unconcrete VarName
mhauru Jan 9, 2026
7857eae
Misc bugfixes
mhauru Jan 9, 2026
16fe150
Stop running SVI and VNT tests
mhauru Jan 9, 2026
51a518f
Fix LDF bug
mhauru Jan 12, 2026
1950a93
Fix some bugs, simplify (inv)linking
mhauru Jan 12, 2026
051521a
Fix some tests
mhauru Jan 12, 2026
9812ad0
Comment back in include of old VI files
mhauru Jan 12, 2026
6d44954
Remote JET extension and experimental.jl
mhauru Jan 12, 2026
d5bfa2c
Reimplement bijector.jl
mhauru Jan 12, 2026
eb903e1
Move linking code to VarInfo, fix ProductNamedDistribution bijector, etc
mhauru Jan 12, 2026
469a715
Mark a test as broken
mhauru Jan 12, 2026
89a8396
Various bugfixes
mhauru Jan 12, 2026
8cf8ab0
Remove SimpleVarInfo, VarNamedVector, and the old VarInfo type
mhauru Jan 12, 2026
8ba36f6
Fix a lot of doctests
mhauru Jan 13, 2026
1f6335d
Rename vntvarinfo.jl to varinfo.jl
mhauru Jan 13, 2026
dbcf5f6
Rename VNTVarInfo to VarInfo
mhauru Jan 13, 2026
0edaa53
Remove (un)typed_varinfo
mhauru Jan 13, 2026
c2748a7
Add docstrings to varinfo.jl
mhauru Jan 13, 2026
6dbae23
Simplify transformations
mhauru Jan 13, 2026
2fa7333
Fix docs
mhauru Jan 13, 2026
7cbc4a7
Mark some inference tests as broken on 1.10
mhauru Jan 13, 2026
b4361c0
Polish VNT and tests
mhauru Jan 13, 2026
73e50df
Fix broken test marking
mhauru Jan 13, 2026
922fbb6
Polish varinfo.jl
mhauru Jan 13, 2026
66c7970
Polish internal docs
mhauru Jan 13, 2026
51fdcbe
More broken inference tests on v1.10
mhauru Jan 13, 2026
07a13c4
Export VarNamedTuple and its functions
mhauru Jan 14, 2026
92dd490
Add HISTROY.md entry on the new VarInfo
mhauru Jan 14, 2026
06f6c1e
Apply suggestions from code review
mhauru Jan 14, 2026
4f893bc
Use SkipSizeCheck rather than Val(:pass)
mhauru Jan 14, 2026
fdb1373
Remove getindex with dist argument
mhauru Jan 14, 2026
a023a7f
Simplify map and mapreduce for VNT
mhauru Jan 14, 2026
c369b09
Remove unused utility functions
mhauru Jan 15, 2026
6128a56
Use OnlyAccsVarInfo in extract_priors
mhauru Jan 15, 2026
8fddfef
Make linking status a type parameter of VarInfo
mhauru Jan 15, 2026
aa3adb3
Fix a typo
mhauru Jan 15, 2026
0c03233
Simplify code
mhauru Jan 15, 2026
39df57b
Fix comments, remove dead line
mhauru Jan 15, 2026
6ee7187
Merge branch 'mhauru/vnt-for-fastldf' into breaking
penelopeysm Jan 17, 2026
2a2af08
Merge remote-tracking branch 'origin/main' into breaking
penelopeysm Jan 17, 2026
ea9b07a
fix broken test
penelopeysm Jan 17, 2026
65173b6
AbstractPPL 0.14 - new VarName optics & modifications to VNT (#1203)
penelopeysm Jan 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,175 @@
# DynamicPPL Changelog

## 0.40

### `VarNamedTuple`

DynamicPPL now exports a new type, called `VarNamedTuple`, which stores values keyed by `VarName`s.
With it are exported a few new functions for using it: `map_values!!`, `map_pairs!!`, `apply!!`.
Our documentation's Internals section now has a page about `VarNamedTuple`, how it works, and what it's good for.

`VarNamedTuple` is now used internally in many different parts: In `VarInfo`, in `values_as_in_model`, in `LogDensityFunction`, etc.
Almost all of the below changes are the consequence from switching over to using `VarNamedTuple` for various features internally.

### Overhaul of `VarInfo`

DynamicPPL tracks variable values during model execution using one of the `AbstractVarInfo` types.
Previously, there were many versions of them: `VarInfo`, both "typed" and "untyped", and `SimpleVarInfo` with both `NamedTuple` and `OrderedDict` as storage backends.
These have all been replaced by a rewritten implementation of `VarInfo`.
While the basics of the `VarInfo` interface remain the same, this brings with it many changes:

#### No more many `AbstractVarInfo` types

`SimpleVarInfo`, `untyped_varinfo`, `typed_varinfo`, and many other constructors, some exported some not, have been removed.
The remaining one is `VarInfo(...)`, which can take a model or a collection of values.
See the docstring for details.

Some related types and functions, that weren't exported but may have been used by some, have also been removed, most notably `VarNamedVector` and its associated functions like `loosen_types!!` and `tighten_types!!`.

#### Setting and getting values

Previously the various `AbstractVarInfo` types had a multitude of functions for setting values:
`push!!`, `push!`, `setindex!`, `update!`, `update_internal!`, `insert_internal!`, `reset!`, etc.
These have all been replaced by three functions

- `setindex!!` is the one to use for simply setting a variable in `VarInfo` to a known value. It works regardless of whether the variable already exists.
- `setindex_internal!!` is the one to use for setting the internal, vectorised representation of a variable. See the docstring for details.
- `setindex_with_dist!!` is to be used when you want to set a value, but choose the internal representation based on which distribution this value is a sample for.

The order of the arguments for some of these functions has also changed, and now more closely matches the usual convention for `setindex!!`.

Note that `setindex!` (with a single `!`) is not defined, and thus you can't do `varinfo[varname] = new_value`.

`unflatten` works as before, but has been renamed to `unflatten!!`, since it may mutate the first argument and aliases memory with the second argument (it uses views rather than copies of the input vector).

#### Linking is now safer

`link!!` and `invlink!!` on `VarInfo` used to assume that the prior distribution of a variable didn't change from one execution to another (as it does in e.g. `truncated(dist; lower=x)` where `x` is a random variable).
This is no longer the case.
Linking should thus be safer to do.
The cost to pay is that calls to `link!!` and `invlink!!` (and the non-mutating versions) now trigger a model evaluation, to determine the correct priors to use.

#### Other miscellanea

- The `Experimental` module had functions like `Experimental.determine_suitable_varinfo` for determining which `AbstractVarInfo` type was suitable for a given model. This is now redundant and has been removed.
- `Bijectors.bijector(::Model)`, which creates a bijector from the vectorised variable space of the model to the linked variable space of the model, now has slightly different optional arguments. See the docstring for details.
- `NamedDist` no longer allows variable names with `Colon`s in them, such as `x[:]`.

There are probably also changes to the `VarInfo` interface that we've neglected to document here, since the overhaul of `VarInfo` has been quite complete.
If anything related to `VarInfo` is behaving unexpectedly, e.g. the arguments or return type of a function seem to have changed, please check the docstring, which should be comprehensive.

#### Performance benefits

The purpose of this overhaul of `VarInfo` is code simplification and performance benefits.

TODO(mhauru) Add some basic summary of what has gotten faster by how much.

### Changes to indexing random variables with square brackets

0.40 internally reimplements how DynamicPPL handles random variables like `x[1]`, `x.y[2,2]`, and `x[:,1:4,5]`, i.e. ones that use indexing with square brackets.
Most of this is invisible to users, but it has some effects that show on the surface.
The gist of the changes is that any indexing by square brackets is now implicitly assumed to be indexing into a regular `Base.Array`, with 1-based indexing.
The general effect this has is that the new rules on what is and isn't allowed are stricter, forbidding some old syntax that used to be allowed, and at the same time guaranteeing that it works correctly.
(Previously there were some sharp edges around these sorts of variable names.)

#### No more linear indexing of multidimensional arrays

Previously you could do this:

```julia
x = Array{Float64,2}(undef, (2, 2))
x[1] ~ Normal()
x[1, 1] ~ Normal()
```

Now you can't, this will error.
If you first create a variable like `x[1]`, DynamicPPL from there on assumes that this variable only takes a single index (like a `Vector`).
It will then error if you try to index the same variable with any other number of indices.

The same logic also bans this, which likewise was previously allowed:

```julia
x = Array{Float64,2}(undef, (2, 2))
x[1, 1, 1] ~ Normal()
x[1, 1] ~ Normal()
```

This made use of Julia allowing trailing indices of `1`.

Note that the above models were previously quite dangerous and easy to misuse, because DynamicPPL was oblivious to the fact that e.g. `x[1]` and `x[1,1]` refer to the same element.
Both of the above examples previously created 2-dimensional models, with two distinct random variables, one of which effectively overwrote the other in the model body.

TODO(mhauru) This may cause surprising issues when using `eachindex`, which is generally encouraged, e.g.

```
x = Array{Float64,2}(undef, (3, 3))
for i in eachindex(x)
x[i] ~ Normal()
end
```

Maybe we should fix linear indexing before releasing?

#### No more square bracket indexing with arbitrary keys

Previously you could do this:

```julia
x = Dict()
x["a"] ~ Normal()
```

Now you can't, this will error.
This is because DynamicPPL now assumes that if you are indexing with square brackets, you are dealing with an `Array`, for which `"a"` is not a valid index.
You can still use a dictionary on the left-hand side of a `~` statement as long as the indices are valid indices to an `Array`, e.g. integers.

#### No more unusually indexed arrays, such as `OffsetArrays`

Previously you could do this

```julia
using OffsetArrays
x = OffsetArray(Vector{Float64}(undef, 3), -3)
x[-2] ~ Normal()
0.0 ~ Normal(x[-2])
```

Now you can't, this will error.
This is because DynamicPPL now assumes that if you are indexing with square brackes, you are dealing with an `Array`, for which `-2` is not a valid index.

#### The above limitations are not fundamental

The above, new restrictions to what sort of variable names are allowed aren't fundamental.
With some effort we could e.g. add support for linear indexing, this time done properly, so that e.g. `x[1,1]` and `x[1]` would be the same variable.
Likewise, we could manually add structures to support indexing into dictionaries or `OffsetArrays`.
If this would be useful to you, let us know.

#### This only affects `~` statements

You can still use any arbitrary indexing within your model in statements that don't involve `~`.
For instance, you can use `OffsetArray`s, or linear indexing, as long as you don't put them on the left-hand side of a `~`.

#### Performance benefits

The upside of all these new limitations is that models that use square bracket indexing are now faster.
For instance, take the following model

```julia
@model function f()
x = Vector{Float64}(undef, 1000)
for i in eachindex(x)
x[i] ~ Normal()
end
return 0.0 ~ Normal(sum(x))
end
```

Evaluating the log joint for this model has gotten about 3 times faster in v0.40.

#### Robustness benefits

TODO(mhauru) Add an example here for how this improves `condition`ing, once `condition` uses `VarNamedTuple`.

## 0.39.12

When constructing an `MCMCChains.Chains`, sampler statistics that are not `Union{Real,Missing}` are dropped from the chain (previously this would cause chain construction to fail).
Expand Down
7 changes: 2 additions & 5 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "DynamicPPL"
uuid = "366bfd00-2699-11ea-058f-f148b4cae6d8"
version = "0.39.12"
version = "0.40"

[deps]
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
Expand Down Expand Up @@ -30,7 +30,6 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
MCMCChains = "c7f686f2-ff18-58e9-bc7b-31028e88f75d"
MarginalLogDensities = "f0c3360a-fb8d-11e9-1194-5521fd7ee392"
Expand All @@ -40,15 +39,14 @@ Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6"
DynamicPPLChainRulesCoreExt = ["ChainRulesCore"]
DynamicPPLEnzymeCoreExt = ["EnzymeCore"]
DynamicPPLForwardDiffExt = ["ForwardDiff"]
DynamicPPLJETExt = ["JET"]
DynamicPPLMCMCChainsExt = ["MCMCChains"]
DynamicPPLMarginalLogDensitiesExt = ["MarginalLogDensities"]
DynamicPPLMooncakeExt = ["Mooncake"]

[compat]
ADTypes = "1"
AbstractMCMC = "5.10"
AbstractPPL = "0.13.1"
AbstractPPL = "0.14"
Accessors = "0.1"
BangBang = "0.4.1"
Bijectors = "0.15.11"
Expand All @@ -62,7 +60,6 @@ DocStringExtensions = "0.9"
EnzymeCore = "0.6 - 0.8"
ForwardDiff = "0.10.12, 1"
InteractiveUtils = "1"
JET = "0.9, 0.10, 0.11"
KernelAbstractions = "0.9.33"
LinearAlgebra = "1.6"
LogDensityProblems = "2"
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ DynamicPPL = {path = "../"}
ADTypes = "1.14.0"
Chairmarks = "1.3.1"
Distributions = "0.25.117"
DynamicPPL = "0.39"
DynamicPPL = "0.40"
Enzyme = "0.13"
ForwardDiff = "1"
JSON = "1.3.0"
Expand Down
61 changes: 25 additions & 36 deletions benchmarks/benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ using StableRNGs: StableRNG

rng = StableRNG(23)

colnames = [
"Model", "Dim", "AD Backend", "VarInfo", "Linked", "t(eval)/t(ref)", "t(grad)/t(eval)"
]
colnames = ["Model", "Dim", "AD Backend", "Linked", "t(eval)/t(ref)", "t(grad)/t(eval)"]
function print_results(results_table; to_json=false)
if to_json
# Print to the given file as JSON
Expand Down Expand Up @@ -58,31 +56,26 @@ function run(; to_json=false)
end

# Specify the combinations to test:
# (Model Name, model instance, VarInfo choice, AD backend, linked)
# (Model Name, model instance, AD backend, linked)
chosen_combinations = [
(
"Simple assume observe",
Models.simple_assume_observe(randn(rng)),
:typed,
:forwarddiff,
false,
),
("Smorgasbord", smorgasbord_instance, :typed, :forwarddiff, false),
("Smorgasbord", smorgasbord_instance, :simple_namedtuple, :forwarddiff, true),
("Smorgasbord", smorgasbord_instance, :untyped, :forwarddiff, true),
("Smorgasbord", smorgasbord_instance, :simple_dict, :forwarddiff, true),
("Smorgasbord", smorgasbord_instance, :typed_vector, :forwarddiff, true),
("Smorgasbord", smorgasbord_instance, :untyped_vector, :forwarddiff, true),
("Smorgasbord", smorgasbord_instance, :typed, :reversediff, true),
("Smorgasbord", smorgasbord_instance, :typed, :mooncake, true),
("Smorgasbord", smorgasbord_instance, :typed, :enzyme, true),
("Loop univariate 1k", loop_univariate1k, :typed, :mooncake, true),
("Multivariate 1k", multivariate1k, :typed, :mooncake, true),
("Loop univariate 10k", loop_univariate10k, :typed, :mooncake, true),
("Multivariate 10k", multivariate10k, :typed, :mooncake, true),
("Dynamic", Models.dynamic(), :typed, :mooncake, true),
("Submodel", Models.parent(randn(rng)), :typed, :mooncake, true),
("LDA", lda_instance, :typed, :reversediff, true),
("Smorgasbord", smorgasbord_instance, :forwarddiff, false),
("Smorgasbord", smorgasbord_instance, :forwarddiff, true),
("Smorgasbord", smorgasbord_instance, :reversediff, true),
("Smorgasbord", smorgasbord_instance, :mooncake, true),
("Smorgasbord", smorgasbord_instance, :enzyme, true),
("Loop univariate 1k", loop_univariate1k, :mooncake, true),
("Multivariate 1k", multivariate1k, :mooncake, true),
("Loop univariate 10k", loop_univariate10k, :mooncake, true),
("Multivariate 10k", multivariate10k, :mooncake, true),
("Dynamic", Models.dynamic(), :mooncake, true),
("Submodel", Models.parent(randn(rng)), :mooncake, true),
("LDA", lda_instance, :reversediff, true),
]

# Time running a model-like function that does not use DynamicPPL, as a reference point.
Expand All @@ -94,13 +87,13 @@ function run(; to_json=false)
@info "Reference evaluation time: $(reference_time) seconds"

results_table = Tuple{
String,Int,String,String,Bool,Union{Float64,Missing},Union{Float64,Missing}
String,Int,String,Bool,Union{Float64,Missing},Union{Float64,Missing}
}[]

for (model_name, model, varinfo_choice, adbackend, islinked) in chosen_combinations
@info "Running benchmark for $model_name, $varinfo_choice, $adbackend, $islinked"
for (model_name, model, adbackend, islinked) in chosen_combinations
@info "Running benchmark for $model_name, $adbackend, $islinked"
relative_eval_time, relative_ad_eval_time = try
results = benchmark(model, varinfo_choice, adbackend, islinked)
results = benchmark(model, adbackend, islinked)
@info " t(eval) = $(results.primal_time)"
@info " t(grad) = $(results.grad_time)"
(results.primal_time / reference_time),
Expand All @@ -115,7 +108,6 @@ function run(; to_json=false)
model_name,
model_dimension(model, islinked),
string(adbackend),
string(varinfo_choice),
islinked,
relative_eval_time,
relative_ad_eval_time,
Expand All @@ -131,9 +123,8 @@ struct TestCase
model_name::String
dim::Integer
ad_backend::String
varinfo::String
linked::Bool
TestCase(d::Dict{String,Any}) = new((d[c] for c in colnames[1:5])...)
TestCase(d::Dict{String,Any}) = new((d[c] for c in colnames[1:4])...)
end
function combine(head_filename::String, base_filename::String)
head_results = try
Expand All @@ -148,23 +139,22 @@ function combine(head_filename::String, base_filename::String)
Dict{String,Any}[]
end
@info "Loaded $(length(base_results)) results from $base_filename"
# Identify unique combinations of (Model, Dim, AD Backend, VarInfo, Linked)
# Identify unique combinations of (Model, Dim, AD Backend, Linked)
head_testcases = Dict(
TestCase(d) => (d[colnames[6]], d[colnames[7]]) for d in head_results
TestCase(d) => (d[colnames[5]], d[colnames[6]]) for d in head_results
)
base_testcases = Dict(
TestCase(d) => (d[colnames[6]], d[colnames[7]]) for d in base_results
TestCase(d) => (d[colnames[5]], d[colnames[6]]) for d in base_results
)
all_testcases = union(Set(keys(head_testcases)), Set(keys(base_testcases)))
@info "$(length(all_testcases)) unique test cases found"
sorted_testcases = sort(
collect(all_testcases); by=(c -> (c.model_name, c.linked, c.varinfo, c.ad_backend))
collect(all_testcases); by=(c -> (c.model_name, c.linked, c.ad_backend))
)
results_table = Tuple{
String,
Int,
String,
String,
Bool,
String,
String,
Expand All @@ -179,12 +169,12 @@ function combine(head_filename::String, base_filename::String)
sublabels = ["base", "this PR", "speedup"]
results_colnames = [
[
EmptyCells(5),
EmptyCells(4),
MultiColumn(3, "t(eval) / t(ref)"),
MultiColumn(3, "t(grad) / t(eval)"),
MultiColumn(3, "t(grad) / t(ref)"),
],
[colnames[1:5]..., sublabels..., sublabels..., sublabels...],
[colnames[1:4]..., sublabels..., sublabels..., sublabels...],
]
sprint_float(x::Float64) = @sprintf("%.2f", x)
sprint_float(m::Missing) = "err"
Expand All @@ -211,7 +201,6 @@ function combine(head_filename::String, base_filename::String)
c.model_name,
c.dim,
c.ad_backend,
c.varinfo,
c.linked,
sprint_float(base_eval),
sprint_float(head_eval),
Expand Down
Loading