Voglio chiamare le funzioni nella mia libreria Fortran da Julia. In questo caso, ho una funzione eye
che accetta un intero e restituisce un array bidimensionale di numeri interi.Chiamare una funzione Fortran da Julia, restituendo un array: funzione sconosciuta, segfault?
Il modulo Fortran viene compilato in una libreria condivisa utilizzando
$ gfortran -shared -fPIC -o matrix_routines.so matrix_routines.f90
E da allora in poi sto cercando di chiamare da l'interprete interattivo Julia genere (nome ottenuto dal nm
):
julia> n=5
5
julia> ccall((:__matrix_routines_MOD_eye, "/path/to/library/matrix_routines.so"), Array{Int64,2} , (Ptr{Int64},), &n)
Ciò, tuttavia, si traduce immediatamente in Julia lanciando un segfault a me:
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
Sto chiamando la funzione nel modo sbagliato? Qual è il nome corretto della funzione? (Non sembra essere solo eye
, perché non funziona neanche.)
Come domanda aggiuntiva: Julia fa qualcosa con l'orientamento della memoria degli array risultanti? Fortran e Julia sono entrambi importanti per la colonna, ma mi chiedo se a causa di ccall() Julia potrebbe pensare che dovrebbe metterli in pratica?
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
Gli argomenti facoltativi richiedono un'interfaccia esplicita in Fortran Dovresti sapere cosa stai facendo prima di giocare con il fuoco. La cosa migliore sarebbe utilizzare l'interoperabilità di Fortran 2003 con C (e possibilmente il modulo iso_c_binding). Solo Fortran 2008 (o 15?) Consente l'argomento facoltativo alle procedure interoperabili C. –
Qualsiasi output utile da 'gfortran -Wall -fcheck = all ...'? – rickhg12hs
@VladimirF: Grazie per averlo indicato. Fino ad ora, stavo usando il modulo nel mio programma Fortran, che ovviamente ha un'interfaccia esplicita attraverso il file '.mod'. Nota, ho rimosso l'argomento 'opzionale', ma questo si traduce ancora in un segfault. Stai suggerendo che devo usare 'iso_c_binding'? @ rickhg12hs: No, niente. Nessun avviso. – mSSM