@Thomas008 shares some valuable experiences of using StaticCompiler to generate binaries out from Julia code:
Thanks for sharing this!
@Thomas008 shares some valuable experiences of using StaticCompiler to generate binaries out from Julia code:
Thanks for sharing this!
I benefited a lot from Thomas008’s tutorial on StaticCompiler. I am trying to make a dll of my own, I need to work with array data, but I encountered an error when I tried to compile the following code. I want to know if there is a way to fix it.
function calc(a, b)
a .*= b
return 0
end
path = compile_shlib(calc, (Vector{Int}, Vector{Int}), "./")
gives
┌ Warning: Found pointer references to julia data
│ llvm instruction = %14 = call nonnull {}* inttoptr (i64 140728530324048 to {}* ({}*)*)({}* nonnull %1)
│ name = :ijl_array_copy
│ file = Symbol("C:/workdir/src\\array.c")
│ line = 1176
│ fromC = true
│ inlined = false
└ @ StaticCompiler
The problem is that the operator .* needs GC allocations. So it is not compilable for StaticCompiler.
Wait, I thought x .*= y and other .=-like operators modify x in-place and therefore don’t allocate?
I also thought it modified x in-place. So do I need to write a for loop?
This is not correct:
julia> using BenchmarkTools
julia> x, y = rand(0:9, 5), rand(0:9, 5)
([9, 9, 7, 7, 8], [1, 6, 7, 9, 4])
julia> @ballocated calc(x, y)
0
Oh yes, you are right.
(I gave constants to calc, i.e. calc([1,2],[3,4]), which causes allocations. But using variables, which is the actual use, causes no allocations.)
I can repeat this error on my machine with StaticCompiler, although there are no allocations. This would be something to report to the issues of StaticCompiler:
https://github.com/tshort/StaticCompiler.jl/issues
I don’t think it’s totally clear what we’re allowed to do, but it seems clear we can’t work on Vector{Int}:
To enable code to be statically compiled, consider the following:
- Avoid Julia’s internal allocations. That means don’t bake in use of Arrays or Strings or Dicts. Types from StaticTools can help, like StaticStrings and MallocArrays.
…- Arguments and returned values from
compile_shlibmust be native objects such asInt,Float64, orPtr. They cannot be things likeTuple{Int, Int}because that is not natively sized. Such objects need to be passed by reference instead of by value.
If you want to precompile a function that takes Julia Vector{Int} inputs, stay in base Julia with package precompilation. Other languages won’t even be able to provide a Vector{Int}.
Yes, Vector{Int} is off the table. Either use MallocArrays or define your own vector type, like I did in Successful Static Compilation of Julia Code for use in Production. That also contains some discussion of how to call it from Python.