Ich möchte Funktionen in meiner Fortran-Bibliothek von Julia aufrufen. In diesem Fall habe ich eine Funktion eye
, die eine Ganzzahl annimmt und ein zweidimensionales Array von ganzen Zahlen zurückgibt.Aufruf einer Fortran-Funktion von Julia, Rückgabe eines Arrays: unbekannte Funktion, segfault?
Das Fortran-Modul wird in eine gemeinsame Bibliothek
$ gfortran -shared -fPIC -o matrix_routines.so matrix_routines.f90
mit kompiliert und danach bin ich versucht, es von der interaktiven Julia Interpreter zu nennen wie das (Name von nm
erhalten):
julia> n=5
5
julia> ccall((:__matrix_routines_MOD_eye, "/path/to/library/matrix_routines.so"), Array{Int64,2} , (Ptr{Int64},), &n)
Dies führt jedoch sofort dazu, dass Julia bei mir einen Fehler verursacht:
signal (11): Segmentation fault
__matrix_routines_MOD_eye at /path/to/library/matrix_routines.so (unknown line)
anonymous at no file:0
unknown function (ip: -1137818532)
jl_f_top_eval at /usr/bin/../lib/julia/libjulia.so (unknown line)
eval_user_input at REPL.jl:53
jlcall_eval_user_input_19998 at (unknown line)
jl_apply_generic at /usr/bin/../lib/julia/libjulia.so (unknown line)
anonymous at task.jl:95
jl_handle_stack_switch at /usr/bin/../lib/julia/libjulia.so (unknown line)
julia_trampoline at /usr/bin/../lib/julia/libjulia.so (unknown line)
unknown function (ip: 4199613)
__libc_start_main at /usr/bin/../lib/libc.so.6 (unknown line)
unknown function (ip: 4199667)
unknown function (ip: 0)
zsh: segmentation fault (core dumped) julia
Rufe ich die Funktion falsch an? Wie lautet der korrekte Name der Funktion? (Es scheint nicht nur eye
zu sein, da das auch nicht funktioniert.)
Als eine zusätzliche Frage: tut Julia irgendetwas mit der Speicherorientierung der resultierenden Arrays? Fortran und Julia sind beide Spalte-Major, aber ich frage mich, ob wegen ccall() Julia denken könnte, dass es sie transponieren sollte?
module matrix_routines
implicit none
private
public :: eye
contains
pure function eye(n,offset) result(um) !{{{
integer, intent(in) :: n
integer, intent(in), optional :: offset
integer, dimension(n,n) :: um
integer :: i, l, u, os
um = 0
l = 1
u = n
os = 0
if (present(offset)) then
os = offset
end if
if (abs(os) < n) then
if (os > 0) then
u = n - os
else if (os < 0) then
l = 1 - os
end if
do i=l, u
um(i, i+os) = 1
end do
end if
end function eye !}}}
end module matrix_routines
Optionale Argumente erfordern eine explizite Schnittstelle in Fortran Sie sollten wissen, was Sie tun, bevor Sie mit dem Feuer spielen. Am besten wäre es, den Fortran 2003-Interop mit C (und möglicherweise dem iso_c_binding-Modul) zu verwenden. Nur Fortran 2008 (oder 15?) Erlaubt optionale Argumente für C interoperable Verfahren. –
Jede nützliche Ausgabe von 'gfortran -Wall -fcheck = all ...'? – rickhg12hs
@VladimirF: Vielen Dank, dass Sie darauf hingewiesen haben. Bisher habe ich das Modul in meinem Fortran Programm benutzt, welches natürlich eine explizite Schnittstelle durch die '.mod' Datei hat. Beachten Sie, dass ich das Argument 'optional' entfernt habe, aber dies führt immer noch zu einem segfault. Schlägst du vor, dass ich 'iso_c_binding' benutzen soll? @ rickhg12hs: Nein, überhaupt nichts. Keine Warnungen. – mSSM