Skip to content

rng: preserve explicit random state during density evaluation - #1504

Open
yebai wants to merge 8 commits into
contextsfrom
rng
Open

yebai wants to merge 8 commits into
contextsfrom
rng

Conversation

@yebai

@yebai yebai commented Sep 16, 2026 •

Copy link
Copy Markdown
Member

This adds an rng keyword to LogDensityFunction and passes the same generator through construction, density evaluation, AD preparation and default parameter sampling. With ldf = LogDensityFunction(m; rng=Xoshiro(42)), rand(ldf) and model-body calls to rand(__context__.rng) share that generator. During density evaluation, LHS variables read the supplied parameters, and only body calls through __context__.rng advance the generator. Construction and AD preparation may consume draws, so repeated evaluations of a model that draws randomness need not return identical densities. DynamicPPL.logdensity_internal now takes rng as an optional final positional argument, defaulting to Random.default_rng().

Closes #721.

@yebai
yebai added this pull request to stack #1505 September 16, 2026 21:16
@yebai
yebai requested a balanced review from Copilot September 16, 2026 21:19
@codecov

codecov Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.20%. Comparing base (3febd24) to head (2dc046b).

Additional details and impacted files
@@             Coverage Diff              @@
##           contexts    #1504      +/-   ##
============================================
- Coverage     90.20%   90.20%   -0.01%     
============================================
  Files            49       49              
  Lines          7058     7056       -2     
============================================
- Hits           6367     6365       -2     
  Misses          691      691              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new required RNG argument breaks the documented six-argument logdensity_internal interface.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds explicit RNG propagation to LogDensityFunction, addressing #721 by preserving model-body randomness across construction, evaluation, AD, and sampling.

Changes:

  • Stores and propagates an explicit RNG through density-related workflows.
  • Adds ForwardDiff/Mooncake and nested-model coverage.
  • Documents stochastic-density behavior and limitations.
File summaries
File Description
src/logdensityfunction.jl Adds RNG storage and propagation.
src/chains.jl Uses the LDF RNG during parameter/stat evaluation.
src/subsample.jl Propagates RNG into subsampled LDFs.
src/accumulators/fixed_transforms.jl Supports RNG-controlled transform extraction.
src/test_utils/ad.jl Propagates RNG through AD test utilities.
ext/DynamicPPLMooncakeExt.jl Marks RNG state as non-differentiable.
test/logdensityfunction.jl Tests RNG behavior and nested models.
docs/src/ldf/overview.md Documents stochastic density evaluation.
docs/src/evaluation.md Links evaluation semantics to RNG guidance.
HISTORY.md Records the new API behavior.
Review details
  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/logdensityfunction.jl Outdated
@github-actions

Copy link
Copy Markdown
Contributor

DynamicPPL.jl documentation for PR #1504 is available at:
https://TuringLang.github.io/DynamicPPL.jl/previews/PR1504/

@github-actions

github-actions Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Benchmarks

Performance Ratio: gradient time divided by log-density time.

Primal times are for main (94e4e4a) and this PR (2dc046b). For very small models the gradient ratios vary across runs and machines, so compare the raw timings instead. The benchmarks are meant for DynamicPPL developers and mainly catch obvious allocation and type-stability regressions; see the benchmark notes for details.

================================================================================================================================
                                                                     primal                            gradient                 
                                                             ----------------------  -------------------------------------------
Model                                         dim    linked        main          PR     FwdDiff    RvsDiff    Mooncake    Enzyme
--------------------------------------------------------------------------------------------------------------------------------
Simple assume observe*                          1     false     5.56 ns     4.86 ns        9.14    1077.76        9.77      7.51
Simple assume observe*                          1      true     5.56 ns     4.78 ns        9.45    1027.27        9.55      7.19
Smorgasbord                                   201     false      5.4 μs     4.17 μs       97.36     140.78        5.90      1.30
Smorgasbord                                   201      true     6.46 μs     4.94 μs       96.13     167.35        6.23      1.55
Smorgasbord fixed                             100     false           —     2.13 μs       65.67     159.98        6.12      1.24
Smorgasbord fixed                             100      true           —     2.42 μs       72.34     184.07        7.29      1.49
Smorgasbord partial condition                 201     false           —     4.41 μs       99.00     133.30       12.61       err
Smorgasbord partial condition                 201      true           —     5.22 μs      115.28     154.73       11.61       err
Smorgasbord partial decondition               202     false           —     6.06 μs      103.53      99.47        7.63       err
Smorgasbord partial decondition               202      true           —     7.04 μs       96.92     115.31        7.56       err
NamedTuple-field LHS variable*                  1     false           —     4.77 ns        9.23    1114.98       10.12      7.80
NamedTuple-field LHS variable*                  1      true           —     4.79 ns        9.57    1118.84        9.60      8.22
MvNormal argument-supplied observation*         1     false           —     72.9 ns        1.85     773.32        3.37      1.97
MvNormal argument-supplied observation*         1      true           —     73.0 ns        1.89     776.53        3.24      2.01
Loop univariate 1k                           1000     false     16.9 μs     12.2 μs     1124.53     333.44        4.85      0.82
Loop univariate 1k                           1000      true     18.1 μs     15.4 μs     1442.53     267.58        3.71      0.61
Multivariate 1k                              1000     false     1.05 μs    870.0 ns     3161.40     844.49        1.81      4.15
Multivariate 1k                              1000      true     1.08 μs    899.0 ns     3192.95     803.15        1.75      3.25
Loop univariate 10k                         10000     false    164.0 μs    117.0 μs    30025.70     384.34        4.98      0.74
Loop univariate 10k                         10000      true    178.0 μs    150.0 μs    27471.03     309.15        3.87      0.58
Multivariate 10k                            10000     false     8.69 μs     7.85 μs    58085.79     973.18        1.53      2.70
Multivariate 10k                            10000      true     9.34 μs     7.74 μs    61099.21     939.08        1.72      2.68
Dynamic                                        15     false           —     1.04 μs         err      42.81       12.78      5.95
Dynamic                                        10      true     1.92 μs     1.44 μs        1.74      59.01       10.70      6.90
Submodel*                                       1     false     5.56 ns     4.79 ns        9.18    1220.67        9.96      8.04
Submodel*                                       1      true     5.57 ns      4.8 ns        9.47    1246.03        9.92      9.08
Indexed submodels 3k                            1     false           —     2.88 μs        8.51    1904.06       22.19      1.10
Indexed submodels 3k                            1      true           —     2.94 μs        8.50    1864.93       22.36      1.08
Indexed submodels conditioned                   1     false           —     2.85 μs        8.92    1776.56       25.75      2.13
Indexed submodels conditioned                   1      true           —     2.77 μs       10.51    1990.80       31.58      2.13
LDA                                             6      true     3.89 μs     2.71 μs        1.51      13.33       31.96     35.87
================================================================================================================================
Environment
Julia Version 1.13.1
Commit 96ca370cf0e (2026-09-25 19:34 UTC)
Build Info:
  Official https://julialang.org release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 4 × AMD EPYC 9V74 80-Core Processor
  WORD_SIZE: 64
  LLVM: libLLVM-20.1.8 (ORCJIT, znver4)
  GC: Built with stock GC
Threads: 1 default, 1 interactive, 1 GC (on 4 virtual cores)

@yebai
yebai force-pushed the rng branch 2 times, most recently from 0da944f to b809bf5 Compare October 1, 2026 15:54
@yebai
yebai force-pushed the rng branch 2 times, most recently from 764b28e to 45e0ed5 Compare October 2, 2026 07:22
yebai added a commit that referenced this pull request Oct 2, 2026
Assisted-by: Codex <codex@openai.com>
yebai added a commit that referenced this pull request Oct 3, 2026
Assisted-by: Codex <codex@openai.com>
yebai added a commit that referenced this pull request Oct 3, 2026
Assisted-by: Codex <codex@openai.com>
yebai added a commit that referenced this pull request Oct 10, 2026
Assisted-by: Codex <codex@openai.com>
yebai added a commit that referenced this pull request Oct 10, 2026
Assisted-by: Codex <codex@openai.com>
yebai added 8 commits October 10, 2026 22:16
Assisted-by: Codex <codex@openai.com>
Assisted-by: Codex <codex@openai.com>
Assisted-by: Claude Code <noreply@anthropic.com>
Assisted-by: Claude Code <noreply@anthropic.com>
Assisted-by: Codex <codex@openai.com>
Assisted-by: Codex <codex@openai.com>
Assisted-by: Codex <codex@openai.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Should we always pass rng to the model?

2 participants