你如何在 Julia 的函数中加载模块@everywhere

How do you load a module @everywhere inside a function in Julia

我试图在使用 addprocs 创建我的 worker 后加载一个模块。当在顶层调用 addprocs 时,一切都很好。但是,当我将代码包装在一个函数中时,我无法做同样的事情。

在我的例子中,我正在动态添加工作人员,因此始终在顶层调用 @everywhere using XXX 是不可行的,我需要在函数内执行此操作。

简而言之,这有效:

addprocs(1)
@everywhere using XXX

而这不是:

function myaddprocs()
    addprocs(1)
    @everywhere using XXX
end

有什么想法吗?

你不需要 @everywhere。这对我有用:

addprocs()
using mymodule  # loads code on all procs but brings in to scope only on master process.

这就是你想要的,如果你想然后做 pmap(x->fun(x),workers())fun 是从 mymodule 导出的。你可以在这里阅读:https://docs.julialang.org/en/release-0.6/manual/parallel-computing/#Code-Availability-and-Loading-Packages-1

经过更多调查,我找出了导致我的代码无法运行的一些问题。

  1. 导入必须在addprocs之后进行。如果之前发生过导入,则导入必须以 @everywhere.

  2. 为前缀
  3. 函数内部的顶级表达式(例如using)不起作用,除非包裹在eval语句中。

对我的代码的修复是:

function myaddprocs()
    addprocs(1)
    eval(macroexpand(quote @everywhere using XXX end))
end

例子

我已经在 J​​ulia 0.6.1 上测试了以下代码片段。我还在 SGE 集群 (OGS/GE 2011.11p1) 上使用相同版本测试了它们,方法是将所有 addprocs 替换为 addprocs_sge,并导入 ClusterManagers.jl。以下片段有效:

  • usingaddprocs 之后:

    addprocs(1)
    using SpecialFunctions
    pmap(x->SpecialFunctions.sinint(1), workers())
    
  • using前后addprocs,第二个用@everywhere

    using SpecialFunctions
    addprocs(1)
    @everywhere using SpecialFunctions
    pmap(x->sinint(1), workers())
    
  • usingaddprocs 之后包裹在 eval

    function getprocs()
        addprocs(1)
        eval(Expr(:using,:SpecialFunctions))
        pmap(x->SpecialFunctions.sinint(1), workers())
    end
    getprocs()
    
  • 与之前相同,@everywhere 应用于 eval

    function getprocs()
        addprocs(1)
        @everywhere eval(Expr(:using,:SpecialFunctions))
        pmap(x->sinint(1), workers())
    end
    getprocs()
    
  • 与之前相同,但在 eval 中使用 @everywhere 而不是

    function getprocs()
        addprocs(1)
        eval(macroexpand(quote @everywhere using SpecialFunctions end))
        pmap(x->sinint(1), workers())
    end
    getprocs()
    

另一方面,这些片段不起作用:

  • usingaddprocs

    之前
    using SpecialFunctions
    addprocs(1)
    pmap(x->SpecialFunctions.sinint(1), workers())
    
  • using前后addprocs

    using SpecialFunctions
    addprocs(1)
    using SpecialFunctions
    pmap(x->SpecialFunctions.sinint(1), workers())
    
  • using 函数内

    using SpecialFunctions
    function getprocs()
        addprocs(1)
        @everywhere using SpecialFunctions
        pmap(x->sinint(1), workers())
    end
    getprocs()
    
  • using 函数内

    function getprocs()
        addprocs(1)
        using SpecialFunctions
        pmap(x->SpecialFunctions.sinint(1), workers())
    end
    getprocs()
    

Cako 的解决方案很有用,但我不得不将模块作为第一个参数添加到 macroexpand 中:


eval(macroexpand(Distributed,quote @everywhere using DistributedArrays end))