Closed simonbyrne closed 4 years ago
Since https://github.com/JuliaLang/julia/pull/35574 it should work. I will try it out.
Hm, it indeed doesn't look like it is in there
❯ objdump -t libcg.dylib | grep julia_cg
0000000000006d70 l F __TEXT,__text _jlcapi_julia_cg_33008
00000000002139d0 l F __TEXT,__text _julia_cglobal_tfunc_17765
0000000000006d70 g F __TEXT,__text _julia_cg
What doesn't work here? I tried this PR on 1.5.1 and I get:
❯ ./main
success
You mean that you still get precompile(Tuple{typeof(CG.julia_cg), Ptr{Nothing}, Ptr{Float64}, Ptr{Float64}, UInt64})
?
Ok, I think I figured out that problem. It seems that @ccallable
functions are sometimes not emitted even when running with --trace-compile=stderr
. For example:
~/JuliaPkgs/libcg sb/module*
❯ julia --project --trace-compile=stderr generate_precompile.jl 2>&1 | grep julia_cg
~/JuliaPkgs/libcg sb/module*
But they also "hide" the functions they call from being emitted, so the end result is that nothing gets precompiled. So making the ccallble
a very simple wrapper function and calling the Julia function works around it:
diff --git a/generate_precompile.jl b/generate_precompile.jl
index a670302..a0824f8 100644
--- a/generate_precompile.jl
+++ b/generate_precompile.jl
@@ -17,4 +17,4 @@ end
b = ones(len)
x = zeros(len)
-CG.julia_cg(@cfunction(laplace,Cint,(Ptr{Float64}, Ptr{Float64})), pointer(x), pointer(b), Csize_t(len))
+CG._julia_cg(@cfunction(laplace,Cint,(Ptr{Float64}, Ptr{Float64})), pointer(x), pointer(b), Csize_t(len))
diff --git a/src/CG.jl b/src/CG.jl
index 32bbb8b..39b8809 100644
--- a/src/CG.jl
+++ b/src/CG.jl
@@ -25,6 +25,11 @@ end
Base.@ccallable function julia_cg(fptr::Ptr{Cvoid}, cx::Ptr{Cdouble}, cb::Ptr{Cdouble}, len::Csize_t)::Cint
+ _julia_cg(fptr, cx, cb, len)
+end
+
+# Call this in the precompile script
+function _julia_cg(fptr, cx, cb, len)
try
x = unsafe_wrap(Array, cx, (len,))
b = unsafe_wrap(Array, cb, (len,))
With this I get
❯ julia --project --trace-compile=stderr generate_precompile.jl 2>&1 | grep julia_cg
precompile(Tuple{typeof(CG._julia_cg), Ptr{Nothing}, Ptr{Float64}, Ptr{Float64}, UInt64})
and making the executable:
❯ time ./main
success./main 0.06s user 0.03s system 96% cpu 0.089 total
@KristofferC The problem seems to be that @ccallable
s defined inside modules aren't being exported by the dynamic library.
@KristofferC The problem seems to be that
@ccallable
s defined inside modules aren't being exported by the dynamic library.
Ah, that was just a Julia 1.4 issue.
Okay, it still looks like the @ccallable
entrypoint is not being precompiled (but everything else is):
https://github.com/simonbyrne/libcg/pull/14/checks?check_run_id=1150489900#step:7:4
Ah, that was just a Julia 1.4 issue.
Yep, got fixed in 1.5 in https://github.com/JuliaLang/julia/pull/35574
@KristofferC any idea why the @ccallable
entrypoint isn't being precompiled?:
https://github.com/simonbyrne/libcg/pull/14/checks?check_run_id=1150489900#step:7:4
The reason is that it doesn't show up in the output when running with --trace-compile
and the sysimage is building. Why that happens I don't know. However, since it just passes the arguments to another function is should be extremely quick to compile.
I agree it's odd. It seems I can work around this by adding the C entry point manually to a precompile_statements_file
.
@kristofferc I tried moving the
@ccallable
s into a module, but it doesn't seem to work.