I am still trying to arrive to a workflow where I can set some multithreaded experiment random or fixed given some input depending of the needs.
The code above works for a given (fixed) number of threads, but if I let change the number of threads only the MersenneTwister
implementation remains constant, while the StableRNG
implementation returns an output that depends on the number of threads used. Do you know any workaround I could use ? I would like to keep using StableRNGs to keep my unit tests and output results independent on the specific Julia version.
using Random, StableRNGs, Statistics
function generateParallelRngs(rng::AbstractRNG, n::Integer)
seeds = [rand(rng,100:18446744073709551615) for i in 1:n] # some RNGs have issues with too small seeds
rngs = [deepcopy(rng) for i in 1:n]
return Random.seed!.(rngs,seeds)
end
function myFunction(rng = Random.GLOBAL_RNG)
rngs = generateParallelRngs(rng,Threads.nthreads()) # make new copy instances
results = Array{Float64,1}(undef,30)
masterSeed = rand(rng,100:9999999999999)
Threads.@threads for i in 1:30
tsrng = rngs[Threads.threadid()] # Thread safe random number generator: one RNG per thread
Random.seed!(tsrng,masterSeed+i*10) # Here we let the seed depends on the i of the loop, not the thread: we get same results indipendently of the number of threads
results[i] = sum(rand(tsrng, 1:1000,100))
end
overallResult = mean(results)
return overallResult
end
myFunction(MersenneTwister(123)) # same result whatever the number of threads
myFunction(MersenneTwister(123)) # always same as previous line, as expected
myFunction(StableRNG(123)) # output depends on number of threads (i.e. `julia -t 2` ≠`julia -t 4` outputs)
myFunction(StableRNG(123)) # always same as previous line, as expected