首页 > 解决方案 > 我们如何在 Julia 中并行生成随机数?

问题描述

我正在为蒙特卡罗模拟编写并行化的 julia 代码。这需要我在不同的内核上并行生成随机数。在我的工作站上的一个简单测试代码中,我尝试在 4 个内核上生成随机数并得到以下结果:

julia -p 4

julia> @everywhere using Random

julia> @everywhere x = randn(1)

julia> remotecall_fetch(println,1,x[1])
-1.9348951407543997

julia> remotecall_fetch(println,2,x[1])
      From worker 2:    -1.9348951407543997

julia> remotecall_fetch(println,3,x[1])
      From worker 3:    -1.9348951407543997

julia> remotecall_fetch(println,4,x[1])
      From worker 4:    -1.9348951407543997

我不明白为什么从不同进程中获取的数字会给出完全相同的结果。我不确定是什么错误。我的理解是,使用 @everywhere 宏可以让您在所有进程上并行运行相同的代码。我目前在我的电脑上使用 julia 1.6.0。谢谢你。

更新:感谢您的回复。基本上,我正在寻找的是一个像 x = y 这样的赋值语句,其中 x 和 y 都是工作进程的本地。我试过这样的事情:

julia -p 4

@sync @distributed for i = 1:2
       x = randn(1)
       println(x)
       end
      From worker 3:    [0.4451131733445428]
      From worker 2:    [-0.4875627629008678]
Task (done) @0x00007f1d92037340

julia> remotecall_fetch(println,2,x)
ERROR: UndefVarError: x not defined
Stacktrace:
 [1] top-level scope
   @ REPL[23]:1

这似乎在每个进程上独立生成随机数。但是,我不知道如何访问该变量x了。我试过remotecall_fetch(println, 2,x)了,但变量x似乎没有在工作进程上定义。这非常令人困惑。

我希望有很好的流程图或好的文档来解释并行计算期间 Julia 中变量和表达式的范围。

标签: randomparallel-processingjulia

解决方案


remotecall_fetch从您的本地进程发送x[1]评估(具有 id 1)。您可以通过运行以下代码来检查它:

# julia -p 4

julia> @everywhere x = myid() # make sure x holds a worker number

julia> remotecall_fetch(println, 4, x) # x passed from worker 1 (local machine) to println
      From worker 4:    1

julia> @sync @everywhere println(x) # x is evaluated on worker
1
      From worker 3:    3
      From worker 2:    2
      From worker 4:    4
      From worker 5:    5

julia> @sync @everywhere println($x) # x interpolated from local machine
1
      From worker 4:    1
      From worker 5:    1
      From worker 3:    1
      From worker 2:    1

关于远程机器上的随机数生成,您应该确保在每台机器上创建独立的随机数流。对于大多数情况来说,最简单的方法就是Random.seed!在不同的工作人员上使用具有不同种子的函数。如果您想格外小心,请使用Future.randjump以确保工作进程上的随机数生成器没有重叠。


推荐阅读