缓存Julia模块以在Python中更快地启动和使用

时间:2018-07-21 13:16:43

标签: python julia

我有一个Julia模块,需要从我的python代码库进行接口。为此,我像这样使用pyjulia

import julia

j = julia.Julia()
j.include('./simulation/n-dof/dynamics.jl')
j.using("Dynamics")
print(j.sim([1,2,3],[1,2,3]))

但是,这会减慢一切,因为Julia需要编译我正在使用的模块。

我使用的模块导出1函数,内部使用ForwardDiff进行一些计算。它计算动态系统的导数。在可预见的将来,该模块很可能不会更改。我一直在阅读有关__precompile()__PackageCompiler.jl的信息,但我不太了解其内部工作原理以及如何使用它们。

那么有没有一种方法可以将模块缓存在Julia系统映像中(据我了解,这就是为什么干净的Julia启动速度很快的原因)?还是将其编译为二进制文件然后以某种方式通过python调用更好?我需要能够将参数传递给导出的函数。

我用于测试的动力学模块的示例:

module Dynamics
    function sim(a,b)
        return 1
    end

    export sim

end

1 个答案:

答案 0 :(得分:5)

这是一个复杂的问题。我将给出最简单的方法。我假设您使用的是Julia 0.7(应该很快发布):

A。在Julia中生成一个包;在Julia REPL和Pkg管理器会话中切换到包管理器(您使用]切换到包管理器),写:generate Ex1Ex1将是我们的包)

B。您将创建一个包框架;添加所需的任何依赖项。我假设你的例子很简单。然后将Ex1.jl目录中的文件src更改为:

__precompile__()
module Ex1
export sim
sim(a,b) = 1
precompile(sim, (Int, Int))
end

C。当您强制precompile(sim, (Int, Int))函数进行预编译时,关键行是sim –您必须指定要为其预编译函数的参数类型

D。将Julia目录更改为Ex1软件包的目录,并在Pkg管理器模式下写入activate .以激活软件包

E。在仍处于Pkg管理器模式下时,写precompile;这将触发模块的预编译。您可以在DEPOT_PATH[1]子目录的compiled/v0.7/目录中检查是否创建了Ex1目录,该目录包含带有您软件包的预编译内容的ji文件

如何检查软件包是否已预先编译?退出Julia,然后在Ex1软件包的目录中再次输入它(以得到一个干净的REPL)。现在写:

A。 activate .在Pkg管理器模式下(使Ex1可见)

B。返回正常的Julia模式并运行以下命令:

julia> using Ex1

julia> @time sim(1,1)
  0.000003 seconds (5 allocations: 208 bytes)
1

julia> @time sim(1,1)
  0.000003 seconds (4 allocations: 160 bytes)
1

julia> @time sim(1.0,1.0)
  0.000182 seconds (394 allocations: 26.641 KiB)
1

julia> @time sim(1.0,1.0)
  0.000002 seconds (4 allocations: 160 bytes)
1

您会看到sim(1,1)没有像我们为sim参数预编译(Int,Int)那样被编译,但是sim(1.0,1.0)由于我们没有预编译{{1 }} sim

总结:要理解的关键是您不是预编译函数而是此函数的特定方法。您将必须预编译将以这种方式使用的所有方法。上面说明中的所有其余步骤都是使Julia进行预编译的技术步骤。

要记住的其他问题:

  • 您可以将包构建到系统映像中,这很复杂;您在这里获得了指示:https://docs.julialang.org/en/latest/devdocs/sysimg/;您也可以检出您提到的PackageCompiler.jl,以在此过程中为您提供帮助。可以预料,静态预编译将来会变得更好;
  • 要使您的软件包可预编译,所有依赖项都必须是可预编译的。

我希望以上内容对您有用。