Llamando a Julia desde Lua

Llamando a Julia desde Lua

Este código de ejemplo apareció anteriormente en unpublicación de blog de Aditya, con un pequeño ajuste. Intenté ejecutarlo en Debian 10 (buster), pero falló y apareció el siguiente error.

texlua julia.lua
ERROR: could not load library "/usr/lib/x86_64-linux-gnu/../bin/../lib/x86_64-linux-gnu/julia/sys.so"
/usr/lib/x86_64-linux-gnu/../bin/../lib/x86_64-linux-gnu/julia/sys.so: cannot open shared object file: No such file or directory

Intenté esto tanto con la versión predeterminada de Julia 1.0.3+dfsg-4como con la versión inestable actual 1.1.1+dfsg-1. En ambos casos esto produjo el error que se muestra arriba. También estoy usando un backport de TeX Live 2019 de Debian inestable (Debian 10/buster solo tiene la versión preliminar), con LuaTeX 1.10.0.

Dos personas diferentes informan que este código les funciona en Arch Linux. Uno de ellos es Aditya.

Para citarlo desde el chat:

En mi sistema, la biblioteca que debería cargarse es libjulia.so y está ubicada en /usr/lib/libjulia.so

En mi sistema Debian, julia/sys.soestá instalado, pero no estoy seguro de por qué no se encuentra.

dlocate julia/sys.so
libjulia1: /usr/lib/x86_64-linux-gnu/julia/sys.so

El código sigue.

local ffi = require("ffi")
local JULIA = ffi.load("julia", true)

ffi.cdef [[
void jl_init__threading(void);
typedef struct _jl_value_t jl_value_t;
jl_value_t *jl_eval_string(const char*);
]]

JULIA.jl_init__threading()

code = [[
x = [1 2 3]'
A = [1 0 1; 0 1 1; 1 1 0]

y = x'*A*x

print(y[1])
]]

JULIA.jl_eval_string(code)

Respuesta1

Para funcionar, Julia necesita el tiempo de ejecución del sistema sys.jl. El intérprete de Julia viene con una versión precompilada de este tiempo de ejecución, que se descarga en sys.so. Creo que la resolución de la ruta sys.sopuede verse influenciada de alguna manera estableciendo variables de entorno, pero no pude descubrir cómo. Otra alternativa es apuntar la jl_initfunción a la ruta de la imagen del sistema usando jl_init_with_image.

local ffi = require("ffi")
local JULIA = ffi.load("julia", true)

ffi.cdef [[
void jl_init_with_image__threading(const char *julia_bindir,
                                   const char *image_relative_path);
typedef struct _jl_value_t jl_value_t;
jl_value_t *jl_eval_string(const char*);
]]

JULIA.jl_init_with_image__threading("/usr/lib/x86_64-linux-gnu/julia/", "sys.so")

code = [[
x = [1 2 3]'
A = [1 0 1; 0 1 1; 1 1 0]

y = x'*A*x

print(y[1])
]]

JULIA.jl_eval_string(code)

Guardé este archivo /tmp/julia/test.luay lo ejecuté en un contenedor Docker usando los siguientes comandos:

user@host:~$ sudo docker run -v /usr/local/texlive/2019/:/usr/local/texlive/2019/:ro -v /tmp/julia/:/tmp/julia/ -it --rm debian:buster
root@9903c6e0ca52:/# export PATH=/usr/local/texlive/2019/bin/x86_64-linux/:$PATH
root@9903c6e0ca52:/# apt-get update
[...]
root@9903c6e0ca52:/# apt-get install --no-install-recommends julia libjulia-dev
[...]
root@9903c6e0ca52:/# texlua /tmp/julia/test.lua
23root@9903c6e0ca52:/#

El 23antes root@9903c6e0ca52de la última línea es el resultado de Julia. Esto es lo mismo que obtengo de una sesión interactiva de Julia:

julia> x = [1 2 3]'
3×1 LinearAlgebra.Adjoint{Int64,Array{Int64,2}}:
 1
 2
 3

julia> A = [1 0 1; 0 1 1; 1 1 0]
3×3 Array{Int64,2}:
 1  0  1
 0  1  1
 1  1  0

julia> y = x'*A*x
1×1 Array{Int64,2}:
 23

julia> print(y[1])
23

información relacionada