Open edzer opened 7 months ago
Hi. Thanks for the report.
Some context here on what is happening.
When using a R chunk inside the document, Quarto computation engine binding will be set to engine: knitr
.
This means that all the non R chunk will be run through their knitr support.
python
chunk will be run with reticulate and julia
chunk will be run with JuliaCall (https://github.com/Non-Contradiction/JuliaCall)
The traceback you shared shows that as the error is thrown from JuliaCall
17. JuliaCall:::stdout_capture_command(buffer)
So first thing would be to test that your Julia environment can be called from R using JuliaCall directly (outside of any knitr engine support). What knitr is doing is calling JuliaCall directly with no specific processing
> knitr:::eng_julia
function (options)
{
JuliaCall::eng_juliacall(options)
}
So if possibly I would check that you can run your Julia code from R using JuliaCall in R console - I think there could be a configuration problem at this step somehow.
The JuliaCall website should help : https://non-contradiction.github.io/JuliaCall/index.html#installation
Unless you did check that already, and this is something else...
Though I believe you would get the same error outside of Quarto directly with knitr (knitr::knit()
) or within R Markdown.
Hope it helps.
Thanks @cderv, very helpful! Using a hint from https://github.com/Non-Contradiction/JuliaCall/issues/192 I can get the following to work: the julia script (cli)
using Plots
plot(x->x)
The R script:
library(JuliaCall)
julia_setup()
julia_library("Plots")
a = 1:10
b = rnorm(10)
julia_call("plot", a, b)
but only when called with R_LD_LIBRARY_PATH
set (see https://github.com/Non-Contradiction/JuliaCall/issues/192):
R_LD_LIBRARY_PATH="~/julia-1.9.4/lib/julia/" R -q --vanilla < tst.R
which gives as output:
> library(JuliaCall)
> julia_setup()
Julia version 1.9.4 at location /home/edzer/julia-1.9.4/bin will be used.
Loading setup script for JuliaCall...
Finish loading setup script for JuliaCall.
> julia_library("Plots")
> a = 1:10
> b = rnorm(10)
> julia_call("plot", a, b)
Julia Object of type Plots.Plot{Plots.GRBackend}.
Plot{Plots.GRBackend() n=1}>
Julia exit.
but not the following qmd:
```{r}
1
using Plots
plot(x->x^2)
when compiled with
```bash
R_LD_LIBRARY_PATH="~/julia-1.9.4/lib/julia/" quarto render tst.qmd
it gives me the following output
which points to the same problem as running
R -q --vanilla < tst.R
i.e. without setting R_LD_LIBRARY_PATH
, which outputs
Note that the problem comes from using Plots
, not from the second line. Are there b.t.w. any examples of using quarto documents that combine R and Julia, and handle Julia plots?
I managed to get some environment on Ubuntu 22.04 running to try reproduce the Julia error. I believe this is all some conflicts in library .so version with newest Plots.jl and the fact this is call from R.
First doing something like
R_LD_LIBRARY_PATH="~/julia-1.9.4/lib/julia/" R
Does not work on my side, because changing R_LD_LIBRARY_PATH
which is R default will hide the libR.so
and I get this error.
/opt/R/4.3.2/lib/R/bin/exec/R: error while loading shared libraries: libR.so: cannot open shared object file: No such file or directory
This makes sense to me considering that this is default value set by R itself according to doc (https://cran.r-project.org/doc/manuals/r-release/R-admin.html#External-software-1)
he secondary mechanism is to consult the environment variable LD_LIBRARY_PATH. The R script controls that variable, and sets it to the concatenation of R_LD_LIBRARY_PATH, R_JAVA_LD_LIBRARY_PATH and the environment value of LD_LIBRARY_PATH. The first two have defaults which are normally set when R is installed (but can be overridden in the environment) so LD_LIBRARY_PATH is the best choice for a user to set.
So I am surprised this has worked for you.
However, R_LD_LIBRARY_PATH
is set first, so I could modify the other value to add if I do
export LD_LIBRARY_PATH=/home/cderv/.julia/juliaup/julia-1.9.4+0.x64.linux.gnu/lib/julia/
However, I will still get the error on Julia code from R because I believe the wrong version is looked for in wrong place.
This is to me the heart of the issue
libgobject-2.0.so: undefined symbol: g_bookmark_file_copy
and this seems to be available since fairly recently in Glib 2.76 according to https://docs.gtk.org/glib/method.BookmarkFile.copy.html. So maybe this could be fixed by installing / compiling Plots.jl against an older version maybe or something like this (not enough Julia expert for now).
Anyhow, if I continue trying to set Julia libs fist, I can do inverse top put Julia first
export R_LD_LIBRARY_PATH="/home/cderv/.julia/juliaup/julia-1.9.4+0.x64.linux.gnu/lib/julia/:$(R RHOME)/lib:/opt/local/lib"
Then I can make the R code work. But Quarto rendering still has a problem.
I believe there is then an issue inside Quarto rendering because Quarto calls R through Deno, which call Julia through R and somehow the LD paths got mixed up again at some point.
I would say this is something in how R calls Julia with not setting the Julia Libs first for resolution probably, and some conflict in dynamic library linking.
I'll keep digging next week, but just wanted to share my feedback on what I tried.
Bug description
Having julia chunks leads to error when there is an R chunk too; not in all cases, but e.g. when using
Plots
but also many other packages. The julia chunks work when executed in julia cli, and also when the R chunk is removed (but then the Python section is ignored). When removing the Plots part, doing only the DatFrame and CSV part, the julia chunk does not throw an error.Steps to reproduce
$ quarto render index.qmd
processing file: index.qmd 1/7
2/7 [unnamed-chunk-1] 3/7
4/7 [unnamed-chunk-2] Julia version 1.9.4 at location /home/edzer/julia-1.9.4/bin will be used. Loading setup script for JuliaCall... Finish loading setup script for JuliaCall.
Quitting from lines 8-15 [unnamed-chunk-2] (index.qmd) Error: ! Error happens in Julia. InitError: could not load library "/home/edzer/.julia/artifacts/b6ebc4def1211ec4043d7c055f450d59f56747cc/lib/libgobject-2.0.so" /home/edzer/.julia/artifacts/b6ebc4def1211ec4043d7c055f450d59f56747cc/lib/libgobject-2.0.so: undefined symbol: g_bookmark_file_copy Stacktrace: [1] dlopen(s::String, flags::UInt32; throw_error::Bool) @ Base.Libc.Libdl ./libdl.jl:117 [2] dlopen(s::String, flags::UInt32) @ Base.Libc.Libdl ./libdl.jl:116 [3] macro expansion @ ~/.julia/packages/JLLWrappers/pG9bm/src/products/library_generators.jl:63 [inlined] [4] init() @ Glib_jll ~/.julia/packages/Glib_jll/MZy06/src/wrappers/x86_64-linux-gnu.jl:36 [5] register_restored_modules(sv::Core.SimpleVector, pkg::Base.PkgId, path::String) @ Base ./loading.jl:1115 [6] _include_from_serialized(pkg::Base.PkgId, path::String, ocachepath::String, depmods::Vector{Any}) @ Base ./loading.jl:1061 [7] _tryrequire_from_serialized(modkey::Base.PkgId, path::String, ocachepath::String, sourcepath::String, depmods::Vector{Any}) @ Base ./loading.jl:1391 [8] _require_search_from_serialized(pkg::Base.PkgId, sourcepath::String, build_id::UInt128) @ Base ./loading.jl:1494 [9] _require(pkg::Base.PkgId, env::String) @ Base ./loading.jl:1783 [10] _require_prelocked(uuidkey::Base.PkgId, env::String) @ Base ./loading.jl:1660 [11] macro expansion @ ./loading.jl:1648 [inlined] [12] macro expansion @ ./lock.jl:267 [inlined] [13] require(into::Module, mod::Symbol) @ Base ./loading.jl:1611 [14] top-level scope @ none:3 [15] eval(m::Module, e::Any) @ Core ./boot.jl:370 [16] top-level scope @ ~/R/x86_64-pc-linux-gnu-library/4.3/JuliaCall/julia/RmdStd.jl:15 [17] eval @ ./boot.jl:370 [inlined] [18] eval_string(x::String) @ Main.JuliaCall ~/R/x86_64-pc-linux-gnu-library/4.3/JuliaCall/julia/setup.jl:203 [19] docall(call1::Ptr{Nothing}) @ Main.JuliaCall ~/R/x86_64-pc-linux-gnu-library/4.3/JuliaCall/julia/setup.jl:176 during initialization of module Glib_jll Backtrace:
Your environment
Ubuntu 22.04, nvim
Quarto check output