fortran66のブログ

fortran について書きます。

【メモ帳】Fortran から Swift を呼ぶ その2

関数・配列

関数の戻り値はスタックに積まれて普通に C 言語風にとれるようです。

Fortran の配列が Swift に渡せれば、いずれ Swift で GPU 計算させて Fortran に戻せるだろうという目論見です。FORTRAN 77 式の整合配列を渡すノリで C 風の生ポインタとして参照渡しをすればいいようです。

cloud6.net

関係ないメモ: metal は座標の取り方が左手系。Swift は array も copy in の値渡し。

関数

swift

@_cdecl("pri")
public func pri(n: Int32, p: UnsafeMutablePointer<Float>)  {  
    for i in 1...n {
        print("input=", Float(p[Int(i)]))
        let x = Float(i)
        p[Int(i)] = x*x
    }
} 

Fortran

module test_m
    implicit none
    interface
        subroutine fn(n, x) bind(c, name = 'pri')
            integer, value :: n
            real, intent(in out) :: x(n)
        end subroutine fn
    end interface
end module test_m


program test
    use :: test_m
    implicit none
    integer, parameter :: n = 100
    integer :: i
    real :: x(n) = [(real(i), i = 1, n)]
    print *, 'calling Swift from fortran'
    
    call fn(n, x)

    print '(a, (10f7.1))', 'x=', x
end program test

実行

[a] M1:~/fortran/swift% swiftc fn.swift -emit-library
[a] M1:~/fortran/swift% gfortran libfn.dylib fn.f90  
[a] M1:~/fortran/swift% ./a.out
 calling Swift from fortran
input= 10
         100

配列

参考: qiita.com

swift

@_cdecl("pri")
public func pri(n: Int32, p: UnsafeMutablePointer<Float>)  {
    for i in 1...n {
        print("input=", Float(p[Int(i)]))
        let x = Float(i)
        p[Int(i)] = x*x
    }
} 

Fortran

module test_m
    implicit none
    interface
        subroutine fn(n, x) bind(c, name = 'pri')
            integer, value :: n
            real, intent(in out) :: x(n)
        end subroutine fn
    end interface
end module test_m


program test
    use :: test_m
    implicit none
    integer, parameter :: n = 100
    integer :: i
    real :: x(n) = [(real(i), i = 1, n)]
    print *, 'calling Swift from fortran'
    
    call fn(n, x)

    print '(a, (10f7.1))', 'x=', x
end program test

実行

[a] M1:~/fortran/swift% swiftc arr.swift -emit-library
[a] M1:~/fortran/swift% gfortran libarr.dylib arr.f90 
[a] M1:~/fortran/swift% ./a.out                       
 calling Swift from fortran
input= 2.0
input= 3.0
input= 4.0
input= 5.0
input= 6.0
input= 7.0
input= 8.0
input= 9.0
input= 10.0
input= 11.0
input= 12.0
input= 13.0
input= 14.0
input= 15.0
input= 16.0
input= 17.0
input= 18.0
input= 19.0
input= 20.0
input= 21.0
input= 22.0
input= 23.0
input= 24.0
input= 25.0
input= 26.0
input= 27.0
input= 28.0
input= 29.0
input= 30.0
input= 31.0
input= 32.0
input= 33.0
input= 34.0
input= 35.0
input= 36.0
input= 37.0
input= 38.0
input= 39.0
input= 40.0
input= 41.0
input= 42.0
input= 43.0
input= 44.0
input= 45.0
input= 46.0
input= 47.0
input= 48.0
input= 49.0
input= 50.0
input= 51.0
input= 52.0
input= 53.0
input= 54.0
input= 55.0
input= 56.0
input= 57.0
input= 58.0
input= 59.0
input= 60.0
input= 61.0
input= 62.0
input= 63.0
input= 64.0
input= 65.0
input= 66.0
input= 67.0
input= 68.0
input= 69.0
input= 70.0
input= 71.0
input= 72.0
input= 73.0
input= 74.0
input= 75.0
input= 76.0
input= 77.0
input= 78.0
input= 79.0
input= 80.0
input= 81.0
input= 82.0
input= 83.0
input= 84.0
input= 85.0
input= 86.0
input= 87.0
input= 88.0
input= 89.0
input= 90.0
input= 91.0
input= 92.0
input= 93.0
input= 94.0
input= 95.0
input= 96.0
input= 97.0
input= 98.0
input= 99.0
input= 100.0
input= 0.0
x=    1.0    1.0    4.0    9.0   16.0   25.0   36.0   49.0   64.0   81.0
  100.0  121.0  144.0  169.0  196.0  225.0  256.0  289.0  324.0  361.0
  400.0  441.0  484.0  529.0  576.0  625.0  676.0  729.0  784.0  841.0
  900.0  961.0 1024.0 1089.0 1156.0 1225.0 1296.0 1369.0 1444.0 1521.0
 1600.0 1681.0 1764.0 1849.0 1936.0 2025.0 2116.0 2209.0 2304.0 2401.0
 2500.0 2601.0 2704.0 2809.0 2916.0 3025.0 3136.0 3249.0 3364.0 3481.0
 3600.0 3721.0 3844.0 3969.0 4096.0 4225.0 4356.0 4489.0 4624.0 4761.0
 4900.0 5041.0 5184.0 5329.0 5476.0 5625.0 5776.0 5929.0 6084.0 6241.0
 6400.0 6561.0 6724.0 6889.0 7056.0 7225.0 7396.0 7569.0 7744.0 7921.0
 8100.0 8281.0 8464.0 8649.0 8836.0 9025.0 9216.0 9409.0 9604.0 9801.0