From d1bbf58619f8989f131b1496e2375e528e3f23c6 Mon Sep 17 00:00:00 2001 From: Jitendra Verma Date: Sat, 3 Oct 2026 16:46:25 +0530 Subject: [PATCH] Seed a new rng instead of copying TaskLocalRNG copy on a TaskLocalRNG snapshots the current task local state, so noise processes built back to back started from the same state and produced identical noise. --- src/types.jl | 8 ++++---- test/two_processes.jl | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/types.jl b/src/types.jl index 1366d56..3baa495 100644 --- a/src/types.jl +++ b/src/types.jl @@ -205,7 +205,7 @@ function NoiseProcess{iip}( reset = true, reseed = true, continuous = true, cache = nothing ) where {iip} - rng = rng isa Random.TaskLocalRNG ? copy(rng) : rng + rng = rng isa Random.TaskLocalRNG ? Xoshiro(rand(rng, UInt64)) : rng S₁ = ResettableStacks.ResettableStack{iip}( Tuple{ typeof(t0), typeof(W0), typeof(Z0), @@ -417,7 +417,7 @@ mutable struct SimpleNoiseProcess{ rng = Random.default_rng(), reset = true, reseed = true ) where {iip} - rng = rng isa Random.TaskLocalRNG ? copy(rng) : rng + rng = rng isa Random.TaskLocalRNG ? Xoshiro(rand(rng, UInt64)) : rng if Z0 == nothing Z = nothing curZ = nothing @@ -915,7 +915,7 @@ mutable struct NoiseTransport{T, N, wType, zType, Tt, T2, T3, TRV, Trv, RNGType, reset = true, reseed = true, noise_prototype = W(nothing, nothing, t0, rv) ) where {iip} - rng = rng isa Random.TaskLocalRNG ? copy(rng) : rng + rng = rng isa Random.TaskLocalRNG ? Xoshiro(rand(rng, UInt64)) : rng curt = t0 dt = t0 curW = copy(noise_prototype) @@ -1544,7 +1544,7 @@ function BoxWedgeTail{iip}( rng = Random.default_rng(), reset = true, reseed = true ) where {iip} - rng = rng isa Random.TaskLocalRNG ? copy(rng) : rng + rng = rng isa Random.TaskLocalRNG ? Xoshiro(rand(rng, UInt64)) : rng if Z0 === nothing Z = nothing curZ = nothing diff --git a/test/two_processes.jl b/test/two_processes.jl index e3f6f7c..4762f9c 100644 --- a/test/two_processes.jl +++ b/test/two_processes.jl @@ -33,3 +33,18 @@ Random.seed!(seed); @test norm(soloop.Z - sol.Z) == 0.0 end end + +# https://github.com/SciML/DiffEqNoiseProcess.jl/issues/258 +@testset "Default rng gives each process its own stream" begin + W1 = WienerProcess(0.0, 0.0, 0.0; reseed = false) + W2 = WienerProcess(0.0, 0.0, 0.0; reseed = false) + sol1 = solve(NoiseProblem(W1, (0.0, 1.0)); dt = 0.1) + sol2 = solve(NoiseProblem(W2, (0.0, 1.0)); dt = 0.1) + @test sol1.W != sol2.W + + W3 = WienerProcess(0.0, 0.0, 0.0; rng = Xoshiro(7), reseed = false) + W4 = WienerProcess(0.0, 0.0, 0.0; rng = Xoshiro(7), reseed = false) + sol3 = solve(NoiseProblem(W3, (0.0, 1.0)); dt = 0.1) + sol4 = solve(NoiseProblem(W4, (0.0, 1.0)); dt = 0.1) + @test sol3.W == sol4.W +end