Skip to content

Commit c025875

Browse files
rfourquetJeffBezanson
authored andcommitted
Xoshiro: allow any non-negative integer as a seed, via SHA2_256
1 parent f5ce7c4 commit c025875

File tree

8 files changed

+19
-61
lines changed

8 files changed

+19
-61
lines changed

stdlib/LinearAlgebra/test/dense.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ Random.seed!(1234323)
2222
@testset "for $elty" for elty in (Float32, Float64, ComplexF32, ComplexF64)
2323
ainit = convert(Matrix{elty}, ainit)
2424
for a in (copy(ainit), view(ainit, 1:n, 1:n))
25-
@test cond(a,1) 122.15725126320953 atol=0.5
26-
@test cond(a,2) 78.44837047684149 atol=0.5
27-
@test cond(a,Inf) 174.10761543202744 atol=0.4
28-
@test cond(a[:,1:5]) 6.7492840150789135 atol=0.01
25+
@test cond(a,1) 198.3324294531168 atol=0.5
26+
@test cond(a,2) 85.93920079319506 atol=0.5
27+
@test cond(a,Inf) 149.7523084803039 atol=0.4
28+
@test cond(a[:,1:5]) 8.319279144493297 atol=0.01
2929
@test_throws ArgumentError cond(a,3)
3030
end
3131
end

stdlib/LinearAlgebra/test/eigen.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ end
163163
end
164164

165165
@testset "eigen of an Adjoint" begin
166-
Random.seed!(1)
166+
Random.seed!(4)
167167
A = randn(3,3)
168168
@test eigvals(A') == eigvals(copy(A'))
169169
@test eigen(A') == eigen(copy(A'))

stdlib/Random/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
33

44
[deps]
55
Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
6+
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
67

78
[extras]
89
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

stdlib/Random/src/RNGs.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ end
384384

385385
seed!(rng::_GLOBAL_RNG, ::Nothing) = seed!(rng) # to resolve ambiguity
386386

387-
seed!(seed::Union{Nothing,Integer,Vector{UInt32},Vector{UInt64},NTuple{4,UInt64}}=nothing) =
387+
seed!(seed::Union{Nothing,Integer,Vector{UInt32},Vector{UInt64}}=nothing) =
388388
seed!(GLOBAL_RNG, seed)
389389

390390
rng_native_52(::_GLOBAL_RNG) = rng_native_52(default_rng())

stdlib/Random/src/Random.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ include("DSFMT.jl")
1313
using .DSFMT
1414
using Base.GMP.MPZ
1515
using Base.GMP: Limb
16+
import SHA
1617

1718
using Base: BitInteger, BitInteger_types, BitUnsigned, require_one_based_indexing
1819

stdlib/Random/src/Xoshiro.jl

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -117,65 +117,21 @@ end
117117

118118
# Shared implementation between Xoshiro and TaskLocalRNG -- seeding
119119

120-
function seed!(x::Union{TaskLocalRNG,Xoshiro})
120+
function seed!(rng::Union{TaskLocalRNG,Xoshiro})
121121
# as we get good randomness from RandomDevice, we can skip hashing
122-
parent = RandomDevice()
123-
# Constants have nothing up their sleeve, see task.c
124-
# 0x02011ce34bce797f == hash(UInt(1))|0x01
125-
# 0x5a94851fb48a6e05 == hash(UInt(2))|0x01
126-
# 0x3688cf5d48899fa7 == hash(UInt(3))|0x01
127-
# 0x867b4bb4c42e5661 == hash(UInt(4))|0x01
128-
setstate!(x,
129-
0x02011ce34bce797f * rand(parent, UInt64),
130-
0x5a94851fb48a6e05 * rand(parent, UInt64),
131-
0x3688cf5d48899fa7 * rand(parent, UInt64),
132-
0x867b4bb4c42e5661 * rand(parent, UInt64))
122+
rd = RandomDevice()
123+
setstate!(rng, rand(rd, UInt64), rand(rd, UInt64), rand(rd, UInt64), rand(rd, UInt64))
133124
end
134125

135-
function seed!(rng::Union{TaskLocalRNG,Xoshiro}, seed::NTuple{4,UInt64})
136-
# TODO: Consider a less ad-hoc construction
137-
# We can afford burning a handful of cycles here, and we don't want any
138-
# surprises with respect to bad seeds / bad interactions.
139-
140-
s0 = s = Base.hash_64_64(seed[1])
141-
s1 = s += Base.hash_64_64(seed[2])
142-
s2 = s += Base.hash_64_64(seed[3])
143-
s3 = s += Base.hash_64_64(seed[4])
144-
126+
function seed!(rng::Union{TaskLocalRNG,Xoshiro}, seed::Union{Vector{UInt32}, Vector{UInt64}})
127+
c = SHA.SHA2_256_CTX()
128+
SHA.update!(c, reinterpret(UInt8, seed))
129+
s0, s1, s2, s3 = reinterpret(UInt64, SHA.digest!(c))
145130
setstate!(rng, s0, s1, s2, s3)
146-
147-
rand(rng, UInt64)
148-
rand(rng, UInt64)
149-
rand(rng, UInt64)
150-
rand(rng, UInt64)
151-
rng
152131
end
153132

154-
function seed!(rng::Union{TaskLocalRNG, Xoshiro}, seed::UInt128)
155-
seed0 = seed % UInt64
156-
seed1 = (seed>>>64) % UInt64
157-
seed!(rng, (seed0, seed1, zero(UInt64), zero(UInt64)))
158-
end
159-
seed!(rng::Union{TaskLocalRNG, Xoshiro}, seed::Integer) = seed!(rng, UInt128(seed))
160-
161-
function seed!(rng::Union{TaskLocalRNG, Xoshiro}, seed::AbstractVector{UInt64})
162-
if length(seed) > 4
163-
throw(ArgumentError("seed should have no more than 256 bits"))
164-
end
165-
seed0 = length(seed)>0 ? seed[1] : UInt64(0)
166-
seed1 = length(seed)>1 ? seed[2] : UInt64(0)
167-
seed2 = length(seed)>2 ? seed[3] : UInt64(0)
168-
seed3 = length(seed)>3 ? seed[4] : UInt64(0)
169-
seed!(rng, (seed0, seed1, seed2, seed3))
170-
end
133+
seed!(rng::Union{TaskLocalRNG, Xoshiro}, seed::Integer) = seed!(rng, make_seed(seed))
171134

172-
function seed!(rng::Union{TaskLocalRNG, Xoshiro}, seed::AbstractVector{UInt32})
173-
if iseven(length(seed))
174-
seed!(rng, reinterpret(UInt64, seed))
175-
else
176-
seed!(rng, UInt64[reinterpret(UInt64, @view(seed[begin:end-1])); seed[end] % UInt64])
177-
end
178-
end
179135

180136
@inline function rand(rng::Union{TaskLocalRNG, Xoshiro}, ::SamplerType{UInt128})
181137
first = rand(rng, UInt64)

stdlib/Random/test/runtests.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ end
688688
@testset "$RNG(seed) & Random.seed!(m::$RNG, seed) produce the same stream" for RNG=(MersenneTwister,Xoshiro)
689689
seeds = Any[0, 1, 2, 10000, 10001, rand(UInt32, 8), rand(UInt128, 3)...]
690690
if RNG == Xoshiro
691-
push!(seeds, rand(UInt64, rand(1:4)), Tuple(rand(UInt64, 4)))
691+
push!(seeds, rand(UInt64, rand(1:4)))
692692
end
693693
for seed=seeds
694694
m = RNG(seed)
@@ -699,7 +699,7 @@ end
699699
end
700700

701701
@testset "Random.seed!(seed) sets Random.GLOBAL_SEED" begin
702-
seeds = Any[0, rand(UInt128), rand(UInt64, 4), Tuple(rand(UInt64, 4))]
702+
seeds = Any[0, rand(UInt128), rand(UInt64, 4)]
703703

704704
for seed=seeds
705705
Random.seed!(seed)

stdlib/SparseArrays/test/sparse.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1750,7 +1750,7 @@ end
17501750
A = guardseed(1234321) do
17511751
triu(sprand(10, 10, 0.2))
17521752
end
1753-
@test getcolptr(SparseArrays.droptol!(A, 0.01)) == [1, 1, 3, 4, 5, 6, 7, 11, 13, 15, 18]
1753+
@test getcolptr(SparseArrays.droptol!(A, 0.01)) == [1, 1, 1, 1, 2, 2, 2, 4, 4, 5, 5]
17541754
@test isequal(SparseArrays.droptol!(sparse([1], [1], [1]), 1), SparseMatrixCSC(1, 1, Int[1, 1], Int[], Int[]))
17551755
end
17561756

0 commit comments

Comments
 (0)