在 IJulia 笔记本中的并行处理器上调用 numpy
Calling numpy on parallel processors in IJulia notebook
我想 运行 IJulia notebook 中使用 python 库 numpy 的简单代码。我用 PyCall 调用 numpy:
using PyCall
@pyimport numpy as np
这很好用。然后我想把它分成几个处理器。我添加处理器:
addprocs(4)
然后,我 运行 N/proc 迭代函数 f,其中 proc 是我的处理器数量。我在计算机上的四个处理器之间平均分配负载:
n=round(Int,N/proc);
proc_sum = @parallel (+) for i=1:proc
f(n)
end
return proc_sum / proc
没有 numpy,这工作正常。但是,当我尝试使用 numpy 将代码拆分到不同的处理器时,出现错误
ERROR (unhandled task failure): On worker 3:
UndefVarError: np not defined
有没有办法让 numpy 在其他处理器上工作?请注意,我有 Julia 0.5.2 和 Canopy。我知道之前曾报告过 PyCall 和 Canopy 的问题,但我更愿意将 Canopy 保留在我的机器上。
我正在扩展 Lyndon 的评论以提供更全面的答案。
根据 the documentation,进程是独立的,因此依赖于它们自己的独立工作区。因此,进程需要的任何函数、模块或变量都需要首先提供给该进程。
如果你想让所有现有进程都可以使用某些东西,你可以使用@everywhere
宏;显然,要让某些东西对 "all existing processes" 可用,需要先创建这些进程。
所以:
addprocs(4); # create 4 extra processes (i.e. workers); this is in addition
# to the main process that handles the REPL
@everywhere import Pycall
@everywhere PyCall.@pyimport numpy as np # load module on _all_ 5 active processes
为了进一步扩展已经说过的内容,您需要的一切都应该加载到所有进程中。例如:
addprocs(4)
@everywhere using PyCall
@everywhere @pyimport numpy as np
你写的是错误的,因为所有进程都试图使用 @pyimport
但只有主进程加载了 PyCall
。如果你需要很多包来做你的计算,也许更容易的是在一个脚本中完成所有加载,即 load_modules.jl
然后简单地 运行
addprocs(4)
@everywhere include("load_modules.jl")
编辑:似乎 using
对于 @everywhere
不是很稳健(在 Julia 0.6 上修复,参见 here)。似乎效果更好的是:
addprocs(4)
import PyCall
@everywhere using PyCall
@everywhere @pyimport numpy as np
我想 运行 IJulia notebook 中使用 python 库 numpy 的简单代码。我用 PyCall 调用 numpy:
using PyCall
@pyimport numpy as np
这很好用。然后我想把它分成几个处理器。我添加处理器:
addprocs(4)
然后,我 运行 N/proc 迭代函数 f,其中 proc 是我的处理器数量。我在计算机上的四个处理器之间平均分配负载:
n=round(Int,N/proc); proc_sum = @parallel (+) for i=1:proc f(n) end return proc_sum / proc
没有 numpy,这工作正常。但是,当我尝试使用 numpy 将代码拆分到不同的处理器时,出现错误
ERROR (unhandled task failure): On worker 3:
UndefVarError: np not defined
有没有办法让 numpy 在其他处理器上工作?请注意,我有 Julia 0.5.2 和 Canopy。我知道之前曾报告过 PyCall 和 Canopy 的问题,但我更愿意将 Canopy 保留在我的机器上。
我正在扩展 Lyndon 的评论以提供更全面的答案。
根据 the documentation,进程是独立的,因此依赖于它们自己的独立工作区。因此,进程需要的任何函数、模块或变量都需要首先提供给该进程。
如果你想让所有现有进程都可以使用某些东西,你可以使用@everywhere
宏;显然,要让某些东西对 "all existing processes" 可用,需要先创建这些进程。
所以:
addprocs(4); # create 4 extra processes (i.e. workers); this is in addition
# to the main process that handles the REPL
@everywhere import Pycall
@everywhere PyCall.@pyimport numpy as np # load module on _all_ 5 active processes
为了进一步扩展已经说过的内容,您需要的一切都应该加载到所有进程中。例如:
addprocs(4)
@everywhere using PyCall
@everywhere @pyimport numpy as np
你写的是错误的,因为所有进程都试图使用 @pyimport
但只有主进程加载了 PyCall
。如果你需要很多包来做你的计算,也许更容易的是在一个脚本中完成所有加载,即 load_modules.jl
然后简单地 运行
addprocs(4)
@everywhere include("load_modules.jl")
编辑:似乎 using
对于 @everywhere
不是很稳健(在 Julia 0.6 上修复,参见 here)。似乎效果更好的是:
addprocs(4)
import PyCall
@everywhere using PyCall
@everywhere @pyimport numpy as np