fortran66のブログ

fortran について書きます。

【メモ帳】forpy で Fortran から Python 呼び出し

PythonFortran から呼び出し

以前紹介しましたが続報です。
f:id:fortran66:20180830031240j:plain
fortran66.hatenablog.com

Forpy のニュース

Forpy 紹介ブログが出たようです。作者へのインタビューが載っています。
www.metamost.com

github.com

新たに wiki などもできたようです。
ylikx.github.io


【無料】邪神ちゃんドロップキック(第1話・前半)

【メモ帳】windows DOS 窓からも呼べました。

intel fortran v.18 と intel Python3.6 の組み合わせです。VisualStudio からではなくコマンドラインからコンパイル&実行しました。

set PYTHONHOME=C:\IntelPython3 が必要でした。コンパイル時には、リンク用の情報として C:\IntelPython3\Libs\python36.lib をコマンドラインに付加する必要があります。

D:\Git\Python\forpy-master>set PYTHONHOME=c:\IntelPython3

D:\Git\Python\forpy-master>ifort -fpp forplot.f90 forpy_mod.obj c:\IntelPython3\Libs\python36.lib
インテル(R) 64 対応インテル(R) Visual Fortran コンパイラー (インテル(R) 64 対応アプリケーション用) バージョン 18.0.3.210 ビルド 20180410
(C) 1985-2018 Intel Corporation. 無断での引用、転載を禁じます。

Microsoft (R) Incremental Linker Version 14.15.26726.0
Copyright (C) Microsoft Corporation. All rights reserved.

  • out:forplot.exe
  • subsystem:console

forplot.obj
forpy_mod.obj
c:\IntelPython3\Libs\python36.lib

D:\Git\Python\forpy-master>forplot
Press Ctrl+C to stop WebAgg server
Server is stopped

D:\Git\Python\forpy-master>

f:id:fortran66:20180830031801p:plain

図はブラウザに出ました。

【メモ帳】tuple を無理やり代入式に

Python の tuple は型の異なるものを列挙して派生型定数を作るようなものですが、forpy の api では、はじめに要素数を宣言した後、1要素毎に api 呼び出しで値を詰めてゆく必要があります。

これを class(*) を使って、type の デフォルト・コンストラクタっぽくできるかコンセプトだけ実験してみました。

こんな感じ

type(tuple) :: tu
tu = t_tuple(1, 2.0, 'sun')

原理的に醜くしか出来ないと思いますが、一応は出来る感じです。class(*) 変数引数を百個でも二百個でも列挙羅列し、select type をありとあらゆる型・派生型に対応させてゆけば、何でも tuple に突っ込めるのではないかと思います。

[追記]
関数の出力 tuple の destroy 処理がされていない可能性があります・・・ FINALIZE 処理を入れれば問題ないが・・・

プログラム

    module m_tuple
        use forpy_mod
        implicit none
    contains
	subroutine sub_assign(tup, i, c)
            type(tuple), intent(in out) :: tup
            integer , intent(in) :: i
            class(*), intent(in) :: c
            integer :: ierr
            select type (c)
            type is (integer)
                ierr = tup%setitem(i, c)
            type is (real)
                ierr = tup%setitem(i, c)
            type is (real(8))
                ierr = tup%setitem(i, c)
            type is (character(*))
                ierr = tup%setitem(i, c)
            end select
        end subroutine sub_assign
        
        type(tuple) function t_tuple(c0, c1, c2, c3, c4, c5, c6, c7, c8) result(tup)
            class(*), intent(in), optional :: c0, c1, c2, c3, c4, c5, c6, c7, c8
            integer :: ierr, n
            n = 0
            if (present(c0)) n = 1
            if (present(c1)) n = n + 1
            if (present(c2)) n = n + 1
            if (present(c3)) n = n + 1
            if (present(c4)) n = n + 1
            if (present(c5)) n = n + 1
            if (present(c6)) n = n + 1
            if (present(c7)) n = n + 1
            if (present(c8)) n = n + 1
            ierr = tuple_create(tup, n)

            if (present(c0)) call sub_assign(tup, 0, c0)
            if (present(c1)) call sub_assign(tup, 1, c1)
            if (present(c2)) call sub_assign(tup, 2, c2)
            if (present(c3)) call sub_assign(tup, 3, c3)
            if (present(c4)) call sub_assign(tup, 4, c4)
            if (present(c5)) call sub_assign(tup, 5, c5)
            if (present(c6)) call sub_assign(tup, 6, c6)
            if (present(c7)) call sub_assign(tup, 7, c7)
            if (present(c8)) call sub_assign(tup, 8, c8)
        end function t_tuple
    end module m_tuple

    program test
        use m_tuple
        integer :: ierr
        type(tuple) :: tu1, tu2
        integer :: len_tu
        ierr = forpy_initialize()
        tu1 = t_tuple(1, 2.0, 'sun')
        ierr = tu1%len(len_tu)
        print *, len_tu

        tu2 = t_tuple('one', 2, 3.0, 4.0d0)
        ierr = tu2%len(len_tu)
        print *, len_tu

        call tu1%destroy()
        call tu2%destroy()
        call forpy_finalize()
    end program test

実行結果

O@HP8:~/forpy$ ifort tup.f90 forpy_mod.o `python3-config --ldflags`
O@HP8:~/forpy$ ./a.out
3
4

forpy の API は C 言語的な、関数の戻り値をエラーコードにするという、非 Fortran 的な副作用のある関数を使っているので、育ちのよろしくない感じがしてやや落ち着きませんw

結論:蛇はむかつくw


邪神ちゃんねるV第6話