-
Notifications
You must be signed in to change notification settings - Fork 545
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use dont_dlopen=true with GR libraries #5784
Conversation
We're probably going to need a version bump for this. Alternatively, I'm looking into using Overrides.toml
CC @jheinen |
As long as this patch does not affect the precompile behavior of Explicitly setting the |
To be clear this was originally proposed by @sjkelly and currently exists on the master branch of GR.jl: I'm just running with it here. Originally, the only way I knew how to defer the loading of the binaries was to defer the loading of GR_jll, but that broke precompilation. This allows us to load GR_jll normally while still deferring the actual loading of the binaries. The deferment is important because that gives us the chance to load alternative binaries or not load any binaries at all. The chance allows to build a robust configuration stage, to choose binaries, or to even repair the config. |
An alternative is to use the existing methods in jll to swap out libraries. I started to add functionality like |
I think the idea here is that Plots.jl ships GR by default, but one may not
necessarily want to use use GR as the default backend in e.g. a sysimg.
Making the loading deferred may have some startup and distribution size
improvements.
…On Wed, Nov 2, 2022, 07:17 Valentin Churavy ***@***.***> wrote:
An alternative is to use the existing methods in jll to swap out libraries.
I started to add functionality like set_library in
https://github.com/cesmix-mit/LAMMPS.jl/blob/main/src/LAMMPS.jl#L30 to my
packages.
—
Reply to this email directly, view it on GitHub
<#5784 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAP5MDCVEPVYOSKDWQ73YF3WGJEUJANCNFSM6AAAAAARUQ7QEA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
$ julia -e 'using Pkg; pkg"add BinaryBuilder JLLWrappers"'
$ julia build_tarballs.jl x86_64-linux-gnu --verbose --deploy=local
[...]
$ julia -e 'using JLLWrappers; JLLWrappers.dev_jll("GR")'
[...]
[ Info: GR_jll dev\'ed out to ~/.julia/dev/GR_jll with pre-populated override directory
$ julia -e 'using Pkg; Pkg.develop(path="~/.julia/dev/GR_jll")'
[...]
$ julia -e 'using Plots; png(plot(1:2), "foo")' # looks good (uses libGR.so)
$ julia -e 'using Plots; x = y = -3:0.1:3; png(surface(x, y, (x, y) -> sinc(sqrt(x^2 + y^2))), "bar")' # looks good (uses libGR3.so)
$ julia -e 'using Plots; display(plot(1:2)); println("press any key"); readline()' # OK, uses libGKS.so |
Yes, I'm also pursuing the Preferences.jl based overrides system. I see this as complementary to that approach. The overrides system let's us switch binaries, but what if we do not need to load either binary at all because we are using another Plots backend? |
Currently, |
Exactly, but when are the binaries actually loaded via If GR_jll.jl does not To summarize, the call chain is as follows.
In summary, when Plots.jl does |
Slightly tangential... @mkitti this is a really nice summary of your design and dlsym caching mechanism. I did some benchmarks a while ago when I was looking at it, and it was something like 10x faster than normal |
@jheinen , to clarify, this pull request resolves the |
Thanks! The one reservation I have about this exact approach is that is very lazy and uses a mutable struct as a function pointer cache. An alternative approach would be load all the symbols at once into an immutable struct. I believe that may save some indirection later during normal use. For GR.jl and Plots.jl, I think maximum laziness is the right approach. I'm not sure if other packages would want to be as lazy. For example in JavaCall.jl, all the symbols are loaded into an immutable struct. https://github.com/JuliaInterop/JavaCall.jl/blob/63026e4cc6530c65b791519f34812e84ec843b14/src/jnienv.jl#L3 What I would want to automate in the future is extraction of the symbol table for the shared library. |
Thanks for checking in. I'm currently testing via: I'm going to finish some local testing, and then I will ping Mose. |
Loading GR_jll locally works for basic plotting. (tmp.mFM5iDWhYr) pkg> add GR
Updating registry at `~/.julia/registries/General.toml`
Resolving package versions...
No Changes to `/tmp/tmp.mFM5iDWhYr/Project.toml`
No Changes to `/tmp/tmp.mFM5iDWhYr/Manifest.toml`
(tmp.mFM5iDWhYr) pkg> dev GR_jll
Resolving package versions...
Updating `/tmp/tmp.mFM5iDWhYr/Project.toml`
[d2c73de3] ~ GR_jll v0.69.1+0 ⇒ v0.69.1+1 `~/.julia/dev/GR_jll`
Updating `/tmp/tmp.mFM5iDWhYr/Manifest.toml`
[d2c73de3] ~ GR_jll v0.69.1+0 ⇒ v0.69.1+1 `~/.julia/dev/GR_jll`
julia> using GR
[ Info: Precompiling GR [28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71]
julia> x = [0, 0.2, 0.4, 0.6, 0.8, 1.0]; y = [0.3, 0.5, 0.4, 0.2, 0.6, 0.7]
6-element Vector{Float64}:
0.3
0.5
0.4
0.2
0.6
0.7
julia> plot(x,y) |
But are you actually calling into libgr provided by gr_jll? Where does the manual dlopen happen? Edit: nevermind, you shared the link above: https://github.com/jheinen/GR.jl/blob/5cf55bcf5e99653ff79e827ebfc8c073515744fb/src/funcptrs.jl#L33-L35 |
Setting PATH globally looks like a bad idea: https://github.com/jheinen/GR.jl/blob/5cf55bcf5e99653ff79e827ebfc8c073515744fb/src/funcptrs.jl#L38 |
I agree, we tried multiple times to remove that before, but without success: removing it breaks |
Looks like I can change libraries after loading the module if I set the
|
@giordano I'm good to merge this. I'll look into the PATH issue on Windows. |
For the record this was yanked, since we need a few lines in GR.jl for this to work: |
GR uses a Preferences.jl mechanism to
dlopen
the libraries so the GR_jll does not need to dlopen the binaries directly:https://github.com/jheinen/GR.jl/blob/f224e831abbade86ad1932a8b4b7fa2c85cec86d/src/funcptrs.jl#L33-L35
On Linux in certain configurations, a LD_PRELOAD is needed to get around this since the GR_jll binaries may be loaded before the system binaries. This pull request resolves this, but having GR_jll not load the binaries.
I'm also looking into using Overrides.toml or local preferences for overrides. Even with JLL overrides, this is still needed in case someone wants to use a Plots.jl backend that is not GR. In that case, using dlopen on GR_jll would just add time to loading. Additionally, GR_jll may interfere with other binaries making it difficult to load another backend like PyPlot.jl.
xref: jheinen/GR.jl#483 (comment)
xref: sciapp/gr#141 (comment)
Do we need a version bump for this?