1
1
module DynamicPPLBenchmarks
2
2
3
3
using DynamicPPL: VarInfo, SimpleVarInfo, VarName
4
- using BenchmarkTools: BenchmarkGroup
5
- using TuringBenchmarking: make_turing_suite
4
+ using BenchmarkTools: BenchmarkGroup, @benchmarkable
5
+ using DynamicPPL: DynamicPPL
6
+ using ADTypes: ADTypes
7
+ using LogDensityProblems: LogDensityProblems
8
+
9
+ # Load some the default backends to trigger conditional loading.
10
+ using ForwardDiff: ForwardDiff
11
+ using ReverseDiff: ReverseDiff
6
12
7
13
include (" ./Models.jl" )
8
14
using . Models: Models
9
15
10
16
export Models, make_suite
11
17
18
+ # Utility functions for representing AD backends using symbols.
19
+ # Copied from TuringBenchmarking.jl.
20
+ const SYMBOL_TO_BACKEND = Dict (
21
+ :forwarddiff => ADTypes. AutoForwardDiff (; chunksize= 0 ),
22
+ :reversediff => ADTypes. AutoReverseDiff (; compile= false ),
23
+ :reversediff_compiled => ADTypes. AutoReverseDiff (; compile= true ),
24
+ :mooncake => ADTypes. AutoMooncake (; config= nothing ),
25
+ )
26
+
27
+ to_backend (x) = error (" Unknown backend: $x " )
28
+ to_backend (x:: ADTypes.AbstractADType ) = x
29
+ function to_backend (x:: Union{AbstractString,Symbol} )
30
+ k = Symbol (lowercase (string (x)))
31
+ haskey (SYMBOL_TO_BACKEND, k) || error (" Unknown backend: $x " )
32
+ return SYMBOL_TO_BACKEND[k]
33
+ end
34
+
12
35
"""
13
- make_suite(model, varinfo_choice::Symbol, adbackend::Symbol)
36
+ make_suite(model, varinfo_choice::Symbol, adbackend::Symbol, islinked::Bool )
14
37
15
38
Create a benchmark suite for `model` using the selected varinfo type and AD backend.
16
39
Available varinfo choices:
@@ -20,8 +43,10 @@ Available varinfo choices:
20
43
• `:simple_dict` → builds a `SimpleVarInfo{Float64}` from a Dict (pre-populated with the model’s outputs)
21
44
22
45
The AD backend should be specified as a Symbol (e.g. `:forwarddiff`, `:reversediff`, `:zygote`).
46
+
47
+ `islinked` determines whether to link the VarInfo for evaluation.
23
48
"""
24
- function make_suite (model, varinfo_choice:: Symbol , adbackend:: Symbol )
49
+ function make_suite (model, varinfo_choice:: Symbol , adbackend:: Symbol , islinked :: Bool )
25
50
suite = BenchmarkGroup ()
26
51
27
52
vi = if varinfo_choice == :untyped
@@ -40,14 +65,32 @@ function make_suite(model, varinfo_choice::Symbol, adbackend::Symbol)
40
65
error (" Unknown varinfo choice: $varinfo_choice " )
41
66
end
42
67
43
- # Add the AD benchmarking suite.
44
- suite = make_turing_suite (
45
- model;
46
- adbackends= [adbackend],
47
- varinfo= vi,
48
- check_grads= true ,
49
- error_on_failed_backend= true ,
50
- )
68
+ adbackend = to_backend (adbackend)
69
+ context = DynamicPPL. DefaultContext ()
70
+
71
+ if islinked
72
+ vi = DynamicPPL. link (vi, model)
73
+ end
74
+
75
+ # We construct `LogDensityFunction` using different values
76
+ # than the ones we're going to use for the test. Some of the AD backends
77
+ # compile the tape upon `LogDensityFunction` construction, and we want to
78
+ # evaluate using inputs different from those that the tape was compiled for.
79
+ f = DynamicPPL. LogDensityFunction (model, vi, context; adtype= adbackend)
80
+
81
+ # The parameters at which we evaluate f.
82
+ θ = if islinked
83
+ randn (length (vi[:]))
84
+ else
85
+ rand (Vector, model)
86
+ end
87
+
88
+ # Run once to trigger compilation.
89
+ LogDensityProblems. logdensity_and_gradient (f, θ)
90
+ suite[" gradient" ] = @benchmarkable $ (LogDensityProblems. logdensity_and_gradient)($ f, $ θ)
91
+
92
+ # Also benchmark just standard model evaluation because why not.
93
+ suite[" evaluation" ] = @benchmarkable $ (DynamicPPL. evaluate!!)($ model, $ vi, $ context)
51
94
52
95
return suite
53
96
end
0 commit comments