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

标签 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 进行一些计算。它计算动态系统的导数。在可预见的 future ,该模块很可能不会改变。我一直在阅读有关 __precompile()__PackageCompiler.jl 的内容,但我不太了解内部工作原理以及如何使用它。

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

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

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

    export sim

end

最佳答案

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

一个。在 Julia 中生成一个包;在 Julia REPL 和 Pkg 管理器 session 中切换到包管理器(您使用 ] 切换到它)写入:generate Ex1(Ex1 将是我们的包)

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

__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;这将触发模块的预编译。您可以在 compiled/v0.7/ 子目录中的 DEPOT_PATH[1] 目录中检查创建了 Ex1 目录,它包含 ji 包含预编译包内容的文件

如何检查包是否真的预编译了?退出 Julia 并再次进入 Ex1 包的目录(以获得干净的 REPL)。现在写:

一个。 在 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) 没有编译,因为我们已经为 (Int,Int) 参数预编译了 sim,但是 sim(1.0,1.0) 必须编译,因为我们没有为 (Float64,Float64) 预编译 sim

总而言之:要理解的关键是您预编译的不是函数,而是该函数的特定方法。您将必须预编译您将以这种方式使用的所有方法。上面解释中的所有其余部分都是让 Julia 进行预编译的技术步骤。

要记住的其他问题:

  • 你可以把包构建到系统镜像中,这很复杂;这里有说明:https://docs.julialang.org/en/latest/devdocs/sysimg/ ;您还可以查看您提到的 PackageCompiler.jl 以帮助您完成此过程;可以预见静态预编译在未来会变得更好;
  • 为了使您的包可预编译,所有依赖项都必须是可预编译的。

希望以上内容对您有用。

关于python - 缓存 Julia 模块以在 Python 中更快地启动和使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51456464/

相关文章:

python - 如何在按下某个键时显示图片?

python - 如何在 models.py 之外引用信号

dataframe - julia 创建一个空数据框并向其追加行

julia - 在 Julia 中绘制数据帧上的简单移动平均线

python - 在扭曲的网络下运行 Django 测试服务器

Python ctypes 无法在结构中传递内存数组

matplotlib - Julia Plots : PyCall. PyError("PyImport_ImportModule\n\npyimport 找不到 Python 包 matplotlib.pyplot

lisp - Elixir 和 Julia 之类的语言在什么意义上是同音的?

julia - 反引号表示法中的可选参数

python - 如何在连字符之前获取字符串