我在将Julia的二维阵列传递给Fortran时遇到了麻烦。
将该2d数组传递给C函数可以正常工作。
这是C代码:
#include <stdio.h>
double meanFilter(int **arr, int row, int col)
{
int i, j, sum=0;
float mean;
for (i=0; i<row; i=i+1)
for (j=0; j<col; j=j+1) {
sum = sum + arr[i][j];
printf("%d %d %d %d\n", i, j, arr[i][j], sum);
}
mean = (double)sum / (row * col);
printf("mean=%f\n", mean);
return mean;
}
我用
编译icc -o myclib.so myclib.c -fPIC -shared
和我调用C函数的Julia代码:
x = zeros(Cint,5,5)
for i=1:5
for j=1:5
x[i,j] = i * j
print(x[i,j], " ")
end
println()
end
refAr = [Ref(x,i) for i=1:size(x,1):length(x)]
aMean = ccall((:meanFilter, :myclib), Float64, (Ptr{Ptr{Cint}}, Cint, Cint), refAr, 5, 5)
println("mean_c=",aMean)
我得到了这个输出:
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
0 0 1 1
0 1 2 3
0 2 3 6
0 3 4 10
0 4 5 15
1 0 2 17
1 1 4 21
1 2 6 27
1 3 8 35
1 4 10 45
2 0 3 48
2 1 6 54
2 2 9 63
2 3 12 75
2 4 15 90
3 0 4 94
3 1 8 102
3 2 12 114
3 3 16 130
3 4 20 150
4 0 5 155
4 1 10 165
4 2 15 180
4 3 20 200
4 4 25 225
mean=9.000000
mean_c=9.0
这是Fortran版本:
real(kind=8) function meanFilter(arr, row, col)
integer, intent(in) :: row, col
integer, dimension(row,col), intent(in) :: arr
integer :: i, j, sum
sum = 0
do j=1, col
do i = 1, row
sum = sum + arr(i,j)
write(*,*) i, j, arr(i,j), sum
enddo
enddo
meanFilter = real(sum,8)/(row*col)
write(*,*) "mean=", meanFilter
end function meanFilter
我按照这样编译:
ifort -o myflib.so myflib.f90 -assume byterecl -shared -fPIC
和朱莉娅代码
x = zeros(Cint,5,5)
for i=1:5
for j=1:5
x[i,j] = i * j
print(x[i,j], " ")
end
println()
end
refAr = [Ref(x,i) for i=1:size(x,1):length(x)]
aMean = ccall((:simplemodule_mp_meanfilter_, :myflib), Float64, (Ptr{Ptr{Cint}}, Cint, Cint), refAr, 5, 5)
println("mean_f=",aMean)
我得到了这个输出:
signal (11): Segmentation fault
while loading ./fortran_call_in_julia.jl, in expression starting on line 56
simplemodule_mp_meanfilter_ at ./myflib.so (unknown line)
anonymous at ./<missing> (unknown line)
unknown function (ip: 0x2ab08d75fcfa)
unknown function (ip: 0x2ab08d73b606)
jl_load at /usr/bin/../lib64/libjulia.so.0.6 (unknown line)
unknown function (ip: 0x2ab0991bd4e5)
unknown function (ip: 0x2ab0991bd6bb)
jl_apply_generic at /usr/bin/../lib64/libjulia.so.0.6 (unknown line)
unknown function (ip: 0x2ab0990625bf)
unknown function (ip: 0x2ab09906262b)
jl_apply_generic at /usr/bin/../lib64/libjulia.so.0.6 (unknown line)
unknown function (ip: 0x2ab0991c6315)
unknown function (ip: 0x2ab0991c87f4)
unknown function (ip: 0x2ab0991c9288)
jl_apply_generic at /usr/bin/../lib64/libjulia.so.0.6 (unknown line)
unknown function (ip: 0x401d90)
unknown function (ip: 0x401592)
__libc_start_main at /usr/bin/../lib64/libc.so.6 (unknown line)
unknown function (ip: 0x401649)
Allocations: 1664692 (Pool: 1663483; Big: 1209); GC: 1
Segmentation fault (core dumped)
那么,对于fortran版本,我做错了什么?
答案 0 :(得分:3)
即使对于简单的积分参数,Fortran仍然使用引用调用。另外,您在这里创建了冗余的间接层(在C和Fortran版本中)。所以纠正你的fortran代码的julia包装应该是:
x = zeros(Cint,5,5)
for i=1:5
for j=1:5
x[i,j] = i * j
print(x[i,j], " ")
end
println()
end
aMean = ccall((:meanfilter_, "./tst.so"), Float64, (Ref{Cint}, Ref{Cint}, Ref{Cint}), x, 5, 5)
println("mean_f=",aMean)
我使用gfortran
对此进行了测试,因此您的名称可能会有所不同。