random - 用于 Julia 集群计算的随机数种子
问题描述
我有一个 Julia 代码,我想通过并行运行大量作业(即大约 10,000 个并行作业)将此代码提交到远程计算集群。这段代码的工作方式是,主函数(称为“main.jl”)调用另一个函数(称为“generator.jl”),该函数利用随机数,例如 rand(Float64) 等。我通过 bash 文件提交 main.jl,并通过包含并行运行 N 个作业
#PBS -t 1-N
我想确保 N 个作业提交中的每一个都有一个不同的随机数生成器,但我不确定如何执行此操作。我正在考虑根据环境变量设置随机种子;即,通过设置
@everywhere import Random.Random
@everywhere using Random.Random
Random.seed!(ENV_VAR)
在 main.jl 中。但是,我不确定如何获取环境变量 ENV_VAR。在 MATLAB 中,我知道我可以通过
NUM = getenv( 'PBS_ARRAYID' )
但我不知道如何在 Julia 中做到这一点。如果我设法在 main.jl 中设置这个新的随机种子,每次 bash 脚本将 main.jl 提交到集群时,这会生成不同的随机种子吗?同样,考虑到 Julia RNG 使用 MersenneTwister,我什至需要在 Julia 中执行此操作吗?
以防万一,我一直在远程机器上使用 Julia 1.5.1。
解决方案
这里有两个问题:
- 获取工作编号
- 在随机数生成中使用作业号。
这些问题中的每一个都有两个解决方案 - 一个更多,另一个不太优雅,但也可以。
广告1。要管理作业编号,请考虑将 PBS 与ClusterManagers.jl
. 那里有一个命令addprocs_pbs(np::Integer; qsub_flags="")
可以管理运行编号并在 Julia 内编排集群。在许多情况下,您会发现这种方法更舒适。在这里,您可以用于播种myid()
返回工人编号的随机数生成器(稍后会详细介绍)。无论如何,在这种情况下,您很可能会使用循环运行您的计算,@distributed
并且您可以使用该值来播种 RNG。如果您宁愿通过 bash 脚本在外部编排数组作业,那么最好的办法是通过参数将作业编号传递给 Julia 进程并从ARGS
变量中读取它,或者使用设置 bash 脚本导出可以从中读取的环境参数ENV
多变的。
广告 2。这里有两种方法。首先,您可以简单地在每个工作人员处创建一个新的 MersseneTwister,然后在流中使用它。举个例子(这里我假设你使用一些变量jobid
):
using Random
rnd = MersenneTwister(jobid)
rand(rnd, 4)
这基本上没问题,并且已知随机流不相关。但是,您可能会担心这种方法会在您的模拟中引入一些工件。如果您想更加小心,您可以使用单个随机流并将其划分为多个进程。这也许也是最先进的解决方案:
using Random, Future
rnd = Future.randjump(MersenneTwister(0), jobid*big(10)^20)
这将使所有进程共享同一个巨大的随机数流(注意,Mersenne Twister 的状态是 19937 位,并且是 19937 位的周期,2^19937 – 1
所以这个跳转的大小一点也不大,big(10)^20
是跳转的推荐步骤,因为它已经在randjump
函数实现中预先计算)。
推荐阅读
- angular - 在 CF 上部署时出错:“ERR 服务命令需要在 Angular 项目中运行,但找不到项目定义。”
- java - 当我关闭数据库时,永远不会从 Spring JPA 调用 TransactionException - 为什么?
- sql - 计算 SQL 中每个类别经过的时间
- node.js - 使用“projects.locations.instances.create”获得 404,firebase + node.js
- swift - 如何在 Swift UI 中从 Cloud Firebase 中检索数组中的数据?
- vba - 在 MS-Access 中将 CURL 请求转换为 VBA xml 对象
- node.js - Nodemailer 谷歌工作区在开发中工作,但在生产中,电子邮件变成垃圾邮件
- javascript - 修改地图内数组中的对象值
- amazon-web-services - 无法从 springboot 应用程序连接到 AWS S3
- events - 在 google data studio 中显示 GA4 事件参数