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

时间:2017-12-07 00:07:55

标签: module julia distributed-computing

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

在我的情况下,我正在动态添加工作程序,因此始终在顶层调用@everywhere using XXX是不可行的,我需要在函数内部执行此操作。

简而言之,这有效:

addprocs(1)
@everywhere using XXX

而这不是:

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

有什么想法吗?

3 个答案:

答案 0 :(得分:4)

经过一番调查后,我找到了一些使我的代码无效的问题。

  1. 导入必须在 addprocs之后发生。如果之前发生了导入,则导入必须以@everywhere作为前缀。

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

  3. 我的代码的修复方法是:

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

    实施例

    我在Julia 0.6.1上测试了以下片段。我还在SGE集群(OGS / GE 2011.11p1)上使用相同版本对它们进行了测试,将所有addprocs替换为addprocs_sge,然后导入ClusterManagers.jl。以下片段有效:

      using之后
    • addprocs

      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())
      
    • usingeval内的addprocs包裹在功能

      之内
      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()
      
    • @everywhere中的eval相同,而不是

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

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

      using

      之前
    • addprocs

      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()
      

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:0)

Cako的解决方案很有帮助,但我必须将模块作为第一个参数添加到macroexpand中:


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