fortran66のブログ

fortran について書きます。

【メモ帳】Fortran から swift を呼ぶ

gfortran から簡単な swift routine 呼び出し

参考:gist.github.com

Swift 側を dll にして呼べば良い様です、

プログラム

swift

@_cdecl("say")
public func say() {
    print("Hey!")
}

fortran

短いのでインタフェースはメインプログラムに書いてもよかった。

module test_m
    implicit none
    interface
        subroutine say() bind(c, name = 'say')
        end subroutine say 
    end interface

end module test_m


program test
    use :: test_m
    implicit none

    print *, 'calling Swift from fortran'
    call say()

end program test

コンパイル手順

arm のバイナリを吐いているようで、ifort だと x64 だから無理とリンカに叱られます。

[a] M1:~/fortran/swift% swiftc test.swift -emit-library                        
[a] M1:~/fortran/swift% gfortran libtest.dylib test.f90 
[a] M1:~/fortran/swift% ./a.out
 calling Swift from fortran
Hey!
[a] M1:~/fortran/swift% 

Metal 情報

プログラム

swift

import Metal

@_cdecl("metal")
public func metal_info() {

    print("Metal: GPU information")
    print("\(MTLCreateSystemDefaultDevice()!.currentAllocatedSize)")


    let devices = MTLCopyAllDevices()

    for device in devices {
        let recommendSize = Double(device.recommendedMaxWorkingSetSize) / pow(2, 30)
        let maxBuffSize   = Double(device.maxBufferLength) / pow(2, 30)
    
        print("\(device.name):" +
              "RecommendedMaxSize=\(recommendSize)GB, " +
              "MaxBufferSize=\(maxBuffSize)GB, " +
              "HasUnifiedMemory=\(device.hasUnifiedMemory)")
        print()
    
        print("apple1:", device.supportsFamily(.apple1))
        print("apple2:", device.supportsFamily(.apple2))
        print("apple3:", device.supportsFamily(.apple3))
        print("apple4:", device.supportsFamily(.apple4))
        print("apple5:", device.supportsFamily(.apple5))
        print("apple6:", device.supportsFamily(.apple6))
        print("apple7:", device.supportsFamily(.apple7))
        print("common1:", device.supportsFamily(.common1))
        print("common2:", device.supportsFamily(.common2))
        print("common3:", device.supportsFamily(.common3))
        print("mac1:", device.supportsFamily(.mac1))
        print("mac2:", device.supportsFamily(.mac2))
        print("macCatalyst1:", device.supportsFamily(.macCatalyst1))
        print("macCatalyst1:", device.supportsFamily(.macCatalyst2))
        print()
    
        print("macOS_GPUFamily1_v1", device.supportsFeatureSet(.macOS_GPUFamily1_v1))
        print("macOS_GPUFamily1_v2", device.supportsFeatureSet(.macOS_GPUFamily1_v2))
        print("macOS_GPUFamily1_v3", device.supportsFeatureSet(.macOS_GPUFamily1_v3))
        print("macOS_GPUFamily1_v4", device.supportsFeatureSet(.macOS_GPUFamily1_v4))
        print("macOS_GPUFamily2_v1", device.supportsFeatureSet(.macOS_GPUFamily2_v1))
        print("macOS_ReadWriteTextureTier2", device.supportsFeatureSet(.macOS_ReadWriteTextureTier2))
        print("osx_GPUFamily1_v1", device.supportsFeatureSet(.osx_GPUFamily1_v1))
        print("osx_GPUFamily1_v2", device.supportsFeatureSet(.osx_GPUFamily1_v2))
        print("osx_ReadWriteTextureTier2", device.supportsFeatureSet(.osx_ReadWriteTextureTier2))
    }

}

fortran

module test_m
    implicit none
    interface
        subroutine metal_info() bind(c, name = 'metal')
        end subroutine metal_info
    end interface

end module test_m


program test
    use :: test_m
    implicit none

    print *, 'calling Swift from fortran'
    call metal_info()

end program test

コンパイル&ゴー

[a] M1:~/fortran/swift% swiftc metal.swift -emit-library  
[a] M1:~/fortran/swift% gfortran libmetal.dylib metal.f90 
[a] M1:~/fortran/swift% ./a.out                         
 calling Swift from fortran
Metal: GPU information
1048576
Apple M1:RecommendedMaxSize=5.333343505859375GB, MaxBufferSize=4.0GB, HasUnifiedMemory=true

apple1: true
apple2: true
apple3: true
apple4: true
apple5: true
apple6: true
apple7: true
common1: true
common2: true
common3: true
mac1: true
mac2: true
macCatalyst1: false
macCatalyst1: false

macOS_GPUFamily1_v1 true
macOS_GPUFamily1_v2 true
macOS_GPUFamily1_v3 true
macOS_GPUFamily1_v4 true
macOS_GPUFamily2_v1 true
macOS_ReadWriteTextureTier2 false
osx_GPUFamily1_v1 true
osx_GPUFamily1_v2 true
osx_ReadWriteTextureTier2 false
[a] M1:~/fortran/swift%