我有一个代码需要很长时间才能运行,比集群上允许的最大walltime更长。它依赖于rand(),所以为了在集群上以多个序列运行代码,我使用
julia> r = copy(Random.GLOBAL_RNG)
捕获全局随机数生成器在运行结束时的状态。我需要将'r‘保存到一个文件中,然后在集群上启动下一次运行时从该文件中读取该变量--本质上是为了能够“从我停止的地方继续”。当我尝试时(使用包DelimitedFiles):
julia> writedlm("rngState.bin",r)
但是,我得到以下错误
ERROR: MethodError: no method matching iterate(::MersenneTwister)
Closest candidates are:
iterate(::Core.SimpleVector) at essentials.jl:568
iterate(::Core.SimpleVector, ::Any) at essentials.jl:568
iterate(::ExponentialBackOff) at error.jl:199
这让我相信Mersenne Twister rng的状态不是可以写入文件的东西。这是正确的吗?有没有人知道如何将GLOBAL_RNG的状态保存到文件中,这样我就可以在以后读回它,从我停止的地方继续?
发布于 2019-11-01 16:12:57
一种方法是使用内置标准库Serialization
的功能
julia> using Random, Serialization
julia> rng = MersenneTwister(); # create random generator
julia> rand(rng, 3)
3-element Array{Float64,1}:
0.3708879403326799
0.46672369641612566
0.5728925387391
julia> open("out.bin", "w") do f
serialize(f, rng) # serialize rng to file
end
julia> rng_loaded = deserialize("out.bin"); # load & deserialize rng from file
julia> rand(rng, 3)
3-element Array{Float64,1}:
0.6210629081706212
0.8568331464134413
0.7247872543135467
julia> rand(rng_loaded, 3) # same numbers
3-element Array{Float64,1}:
0.6210629081706212
0.8568331464134413
0.7247872543135467
您可以使用相同的技术将Random.GLOBAL_RNG
存储到文件中。设置它并不像Random.GLOBAL_RNG = rng_loaded
那么简单,因为您试图在另一个模块中分配一个变量(这是不允许的)。但是,您可以使用copy!(Random.GLOBAL_RNG, rng_loaded)
就地覆盖它。
请注意,原则上,序列化格式可以在将来的Julia版本中更改。在这种情况下,您将无法再读取旧的rng文件。如果您计划存储更长时间的rngs,可以考虑将它们的各个字段存储在HDF5文件中。(你可以找到一些灵感here。)
更新:将我愚蠢的set_global_rng
函数替换为copy!
,正如@Matt B在他的回答中所指出的那样。
发布于 2019-11-01 16:13:59
您正在尝试将RNG编写到一个带分隔符的文件中,但是它的内部结构比简单的CSV所支持的要复杂得多。相反,我会使用序列化模块:
julia> using Random, Serialization
julia> open("rng.jls", "w") do f
serialize(f, Random.GLOBAL_RNG)
end
julia> rand(1, 5)
1×5 Array{Float64,2}:
0.747507 0.279039 0.839956 0.265125 0.194283
julia> open("rng.jls") do f
mt = deserialize(f)
copy!(Random.GLOBAL_RNG, mt)
end
julia> rand(1, 5)
1×5 Array{Float64,2}:
0.747507 0.279039 0.839956 0.265125 0.194283
https://stackoverflow.com/questions/58661944
复制