I have a Julia module I need to interface with from my python codebase. For that I am using pyjulia
like so.
import julia
j = julia.Julia()
j.include('./simulation/n-dof/dynamics.jl')
j.using("Dynamics")
print(j.sim([1,2,3],[1,2,3]))
However, this slows down everything since Julia needs to compile the module I am using.
The module I use exports 1 function and internally uses ForwardDiff
for some calculations. It calculates derivatives of a dynamic system. The module will most probably not change in the foreseeable future. I've been reading about __precompile()__
and PackageCompiler.jl
but I don't quite understand the internal workings and how to use it.
So is there a way to either cache the module in the Julia system image (from what I understand this is why a clean Julia startup is fast)? Or is it better to compile it to a binary and then somehow call it through python? I need to be able to pass arguments to the exported function.
An example of the dynamics module I use for testing:
module Dynamics
function sim(a,b)
return 1
end
export sim
end
This is a complex question. I will give the simplest approach. I assume you use Julia 0.7 (it should be released very soon):
A. generate a package in Julia; switch to package manager in Julia REPL and in Pkg manager session (you switch to it using ]
) write: generate Ex1
(Ex1
will be our package)
B. you will have a package skeleton created; add whatever dependencies you need. I assume your simple example. Then the file Ex1.jl
in src
directory should be changed to:
__precompile__()
module Ex1
export sim
sim(a,b) = 1
precompile(sim, (Int, Int))
end
C. the key line is precompile(sim, (Int, Int))
as you force precompilation of sim
function - you have to specify argument types for which you want the function to be precompiled
D. change Julia directory to the directory of Ex1
package and write activate .
in Pkg manager mode to activate the package
E. while still in Pkg manager mode write precompile
; this will trigger precompilation of your module. You can check in DEPOT_PATH[1]
directory in compiled/v0.7/
subdirectory that Ex1
directory was created and it contains ji
file with precompiled contents of your package
How to check that the package is actually precompiled? Exit Julia and enter it again in the directory of Ex1
package (to have a clean REPL). Now write:
A. activate .
in Pkg manager mode (to have Ex1
visible)
B. go back to normal Julia mode and run the following:
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
You can see that sim(1,1)
is not compiled as we have precompiled sim
for (Int,Int)
arguments, but sim(1.0,1.0)
had to be compiled as we did not precompile sim
for (Float64,Float64)
.
In summary: the key thing to understand is that you precompile not a function but a specific method of this function. You will have to precompile all methods that you would use this way. All the rest in the explanation above are technical steps to get Julia do the precompilation.
Additional issues to keep in mind:
I hope the above works for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With