On Julia 1.10, threaded Particle Gibbs sampling in Turing can segfault during first-time generation of Libtask-callable objects. See here for an example.
MWE
julia +1.10 --threads=4 --project=test -e '
using Turing, Random, Distributions
using Turing: @model
Turing.setprogress!(false)
@model gdemo_d() = begin
s ~ InverseGamma(2, 3)
m ~ Normal(0, sqrt(s))
1.5 ~ Normal(m, sqrt(s))
2.0 ~ Normal(m, sqrt(s))
end
chn = sample(Random.Xoshiro(5), gdemo_d(), PG(10), MCMCThreads(), 1, 2; progress=false)
@assert size(chn) == (1, 2)
'
The crash is probabilistic, so repeat in fresh processes:
for i in $(seq 1 200); do
echo "run $i"
julia +1.10 --threads=4 --project=test mwe.jl || break
done
Unpatched Libtask failed on run 2/200 with signal 11.
Proposed Fix
Make Libtask.build_callable serialised under a global lock, so only one thread performs callable IR generation/cache population at a time. Sketch:
const build_callable_lock = ReentrantLock()
function build_callable(sig::Type{<:Tuple})
lock(build_callable_lock)
try
# existing build_callable body unchanged
finally
unlock(build_callable_lock)
end
end
On Julia 1.10, threaded Particle Gibbs sampling in Turing can segfault during first-time generation of Libtask-callable objects. See here for an example.
MWE
The crash is probabilistic, so repeat in fresh processes:
Unpatched Libtask failed on run 2/200 with signal 11.
Proposed Fix
Make Libtask.build_callable serialised under a global lock, so only one thread performs callable IR generation/cache population at a time. Sketch:
const build_callable_lock = ReentrantLock()