Julia von Lua aus anrufen

Julia von Lua aus anrufen

Dieser Beispielcode erschien zuvor auf einemBlogbeitrag von Aditya, mit einer kleinen Anpassung. Ich habe versucht, es unter Debian 10 (Buster) auszuführen, aber es ist mit dem folgenden Fehler fehlgeschlagen.

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

Ich habe dies sowohl mit der Standardversion von Julia 1.0.3+dfsg-4als auch mit der aktuellen instabilen Version versucht 1.1.1+dfsg-1. In beiden Fällen trat der oben gezeigte Fehler auf. Ich verwende außerdem einen Backport von TeX Live 2019 von Debian instabil (Debian 10/Buster hat nur die Vorabversion) mit LuaTeX 1.10.0.

Zwei verschiedene Personen berichten, dass dieser Code bei ihnen unter Arch Linux funktioniert. Einer von ihnen ist Aditya.

Um ihn aus dem Chat zu zitieren:

Auf meinem System ist die zu ladende Bibliothek libjulia.so und befindet sich unter /usr/lib/libjulia.so

Auf meinem Debian-System julia/sys.soist es installiert, aber ich bin nicht sicher, warum es nicht gefunden wird.

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

Der Code folgt.

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)

Antwort1

Um zu funktionieren, benötigt Julia die Systemlaufzeit sys.jl. Der Julia-Interpreter wird mit einer vorkompilierten Version dieser Laufzeit geliefert, die in gedumpt wird sys.so. Ich denke, dass die Auflösung des Pfads zu sys.soirgendwie durch das Setzen von Umgebungsvariablen beeinflusst werden kann, aber ich konnte nicht herausfinden, wie. Eine andere Alternative besteht darin, die jl_initFunktion mithilfe von auf den Pfad des Systemabbilds zu verweisen 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)

Ich habe diese Datei unter folgendem Namen gespeichert /tmp/julia/test.luaund sie mit den folgenden Befehlen in einem Docker-Container ausgeführt:

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:/#

Das 23„Vorher“ root@9903c6e0ca52in der letzten Zeile ist die Ausgabe von Julia. Das ist dasselbe, was ich von einer interaktiven Julia-Sitzung bekomme:

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

verwandte Informationen