Skip to content

Commit

Permalink
Add a way to reset multiple global random seeds (#2578)
Browse files Browse the repository at this point in the history
  • Loading branch information
fingolfin authored Aug 22, 2023
1 parent 4772781 commit eb7c362
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Polymake = "0.11.1"
Preferences = "1"
RandomExtensions = "0.4.3"
RecipesBase = "1.2.1"
Singular = "0.18.8"
Singular = "0.18.10"
TOPCOM_jll = "0.17.8"
cohomCalg_jll = "0.32.0"
julia = "1.6"
66 changes: 65 additions & 1 deletion src/utils/rand.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# global seed value for oscar to allow creating deterministic random number
# global seed value for OSCAR to allow creating deterministic random number
# generators
# we initialize this here with a random value as well to allow use during
# precompilation
Expand Down Expand Up @@ -33,3 +33,67 @@ be set to a fixed value with `Oscar.set_seed!` as it is done in `runtests.jl`.
"""
get_seeded_rng() = return MersenneTwister([get_seed()])


"""
randseed!(s::Integer)
Reset the random seed for many global RNGs used by OSCAR. Currently that includes:
- the default Julia random source, `Random.default_rng()`
- the default FLINT random source
- the default GAP random source `GlobalMersenneTwister`
- the legacy GAP random source `GlobalRandomSource`
- the Singular random sources
Note that no special steps are taken for thread-local random sources (e.g. the
default Julia random source currently is even task local). Code using multiple
threads or multiple tasks may need to call this function from each thread or
task.
This function is *not* supposed to be called from regular code in Oscar.jl.
Rather it is meant to help with debugging issues that depend on random
sources. E.g. if a computation only fails sometimes, depending on randomness,
it may be possible to make it reproducible by a trick like this:
```julia
seed=0
while true
Oscar.randseed!(seed)
run_tricky_computation()
seed += 1
end
```
Once this throws an exception, we can simply record the value of `seed` at
that time, and use that to make the error reproducible:
```julia
Oscar.randseed!(1234)
run_tricky_computation() # now always throws an exception
```
# Examples
```jldoctest
julia> Oscar.randseed!(1234)
julia> rand(1:1000)
219
julia> GAP.Globals.Random(1,1000)
163
```
"""
randseed!(s::Integer) = randseed!(UInt32(s))

function randseed!(s::UInt32)
# reset Julia random source on the current thread
Random.seed!(s)

# reset FLINT random source on the current thread
Nemo.randseed!(s)

# reset GAP random sources
GAP.randseed!(s)

# reset Singular random sources
Singular.randseed!(s)

return nothing
end

0 comments on commit eb7c362

Please sign in to comment.