Work around a Julia 1.12 codegen bug that crashes ParamsWithStats#1440
Merged
Conversation
Both `ParamsWithStats` model-reevaluation methods selected their accumulator tuple with an `if` before calling `init!!`, so the `(retval, varinfo)` tuple `init!!` returns was `Union`-typed. On Julia 1.12 `-O2` this union is heap-boxed with the unused `retval` pointer fields left uninitialized across a GC safepoint; a GC landing there corrupts the heap and segfaults in `gc_mark_obj8`. It only triggers under concurrent allocation load, which is why it surfaced as a flaky multichain-sampling crash (AbstractMCMC.jl#214). Route both methods through a shared `@noinline _pws_eval` barrier so the accumulator tuple -- and hence the `init!!` result -- is concretely typed at every call site. Behaviour is unchanged. The regression test asserts the union never reappears in the inferred IR of either method: a deterministic, Julia-version-independent guard (only the crash is 1.12-specific). Co-Authored-By: Claude Code <noreply@anthropic.com>
Contributor
|
DynamicPPL.jl documentation for PR #1440 is available at: |
Contributor
Benchmarks @ d36a949Performance Ratio: gradient time divided by log-density time. For very small models these ratios are noisy across runs and machines; raw primal and gradient timings are more reliable. The benchmarks are aimed at DynamicPPL developers and mainly catch obvious allocation or type-stability regressions. See benchmark notes for details. Main @ 29778dfEnvironmentJulia Version 1.11.9 Commit 53a02c0720c (2026-02-06 00:27 UTC) Build Info: Official https://julialang.org/ release Platform Info: OS: Linux (x86_64-linux-gnu) CPU: 4 × INTEL(R) XEON(R) PLATINUM 8573C WORD_SIZE: 64 LLVM: libLLVM-16.0.6 (ORCJIT, sapphirerapids) Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores) |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1440 +/- ##
==========================================
- Coverage 81.64% 81.63% -0.01%
==========================================
Files 50 50
Lines 3579 3578 -1
==========================================
- Hits 2922 2921 -1
Misses 657 657 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Member
|
looks correct to me — thanks |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Under allocation load,
ParamsWithStatsmodel re-evaluation could segfault on Julia 1.12 — a code-generation bug triggered by theUnion-typed valueinit!!returns when the accumulator tuple is chosen before the call. It surfaced as a flaky multichain-sampling crash (AbstractMCMC.jl#214).Both re-evaluation methods now route
init!!through a shared@noinlinebarrier, so that value is concretely typed and the miscompile can't occur. Behaviour is unchanged. The regression test asserts the offendingUnionnever reappears in either method's inferred IR — a deterministic, version-independent guard.The bug is specific to Julia 1.12 at
-O2and reproduces with no Turing stack at all:-O2-O1gc_mark_obj8, within secondsPure-Base MWE (segfaults on Julia 1.12
-O2)Fix TuringLang/AbstractMCMC.jl#214