2017-07-04 72 views
1

我无法从Julia传递2d数组到Fortran。从Julia传递2d数组到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函数编译:

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版本中做错了什么?

回答

3

即使对于简单的积分参数,Fortran也使用引用引用。另外,您正在创建冗余间接层(在C和Fortran版本中)。为你的Fortran代码如此校正朱莉娅包装应该是:

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所以你的名字粉碎可能会有所不同。