Python を Fortran から呼び出し
以前紹介しましたが続報です。
fortran66.hatenablog.com
Forpy のニュース
Forpy 紹介ブログが出たようです。作者へのインタビューが載っています。
www.metamost.com
新たに wiki などもできたようです。
ylikx.github.io
【メモ帳】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.libD:\Git\Python\forpy-master>forplot
Press Ctrl+C to stop WebAgg server
Server is stoppedD:\Git\Python\forpy-master>
図はブラウザに出ました。
【メモ帳】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
- 作者: ユキヲ
- 出版社/メーカー: フレックスコミックス
- 発売日: 2016/04/20
- メディア: Kindle版
- この商品を含むブログ (9件) を見る
forpy の API は C 言語的な、関数の戻り値をエラーコードにするという、非 Fortran 的な副作用のある関数を使っているので、育ちのよろしくない感じがしてやや落ち着きませんw
結論:蛇はむかつくw