-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Random: better handling of the "global seed" (using TLS) (#51526)
We maintain a "global seed" for this feature of `@testset`: > Before the execution of the body of a @testset, there is an implicit call to Random.seed!(seed) where seed is the current seed of the global RNG. Moreover, after the execution of the body, the state of the global RNG is restored to what it was before the @testset. This is meant to ease reproducibility in case of failure, and to allow seamless re-arrangements of @testsets regardless of their side-effect on the global RNG state. But since we don't use `MersenneTwister` as the "global RNG" anymore, we need to maintain a separate "global seed" object. So far we literally used a global object `Random.GLOBAL_SEED` storing the original seed, but it's not robust when multi-tasking is involved: e.g. ```julia seed!(0) x = rand() seed!(0) @sync begin @async @testset "A" begin seed!(1) # reset GLOBAL_SEED to V2 sleep(2) end # reset GLOBAL_SEED to its original value V1 sleep(0.5) @async @testset "B" begin # here seed!(2) above has already been called # so @testset B recorded value V2 as the "original" value of GLOBAL_SEED seed!(2) sleep(2) # here @testset A already finished end # reset GLOBAL_SEED to the wrong original value V2 end @testset "main task" begin # async tests didn't mutate this task's global seed @test x == rand() # fails! end ``` So we store here a "global seed" in `task_local_storage()`, which is set when `seed!()` is invoked without an explicit RNG, and defaults to `Random.GLOBAL_SEED`, which is set only once when `Random` is loaded. And instead of actually storing a seed, we store a copy of the RNG state. This is still not ideal, in that at the beginning of `@testset "A"` or `@testset "B"`, we can't do `@test x == rand()`, because these are in separate tasks, so the global seed defaults to `Random.GLOBAL_SEED`, and not to the global seed of the parent's task; there might be a nice way to handle that, but at least different tasks don't corrupt each-other's seeds.
- Loading branch information
Showing
4 changed files
with
93 additions
and
40 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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