fortran66のブログ

fortran について書きます。

【朗報】謎の技術で Fortran 内から Python 利用

forpy による Fortran Python 相互運用

Fortran プログラム中から Python のデータ構造を使ったり、モジュールの import やコマンド呼び出しが可能であるとともに、逆に Fortran の shared lib として Python のモジュールを作成できるようです。

コンパイラは gfortran/intel どちらも行けるようです。

github.com

驚異の技術です。詳しくは見ていませんが fypp という fortran preprocessor を利用して Python との Link を可能にする C 言語とのインターフェースを生成しているようです。

github.com

bash on ubuntu on windows 上の intel fortran での実行例

サンプルおよびテストは全て、わずかな修正で動作しました。

Matplotlib の実行

Windows10 上の WSL の ubuntu on bash on windows 上にインストールした intel fortran v.18 によってコンパイル&実行しています。

preprocessor が必要なプログラムになっています。intel fortran の場合、 ifort -fpp xx.f90 と -fpp オプションで乗り切れます。

GitHub - ylikx/forpy: Forpy - use Python from Fortran
f:id:fortran66:20180522014342p:plain

intrinsic modules

intel fortranコンパイルするときのオプションは、例題に示されている gfortran のものと同じで良いようです。ただし、ソースプログラム中の、use iso_fortran_env や use iso_c_binding を、use, intrinsic :: iso_fortran_env や use, intrinsic :: iso_c_binding に直す必要がありました。

なお、ファイル拡張子が F90 と大文字になっているので f90 の小文字派の人はうっかりに注意ですw


tests

また tests フォルダー中の Makefike では、コンパイラの指定を ifort にしました。上述のエラーの出るソースファイルでは intrinsic module の修正をする必要があります。 make runtests で全テストを合格しました。

python module

https://github.com/ylikx/forpy#developing-python-modules-in-fortran

元のサンプルのままでは segmentation fault を起こしますが、関数 print_args の宣言行の末尾に bind(c, name = 'print_args') をつけてやれば動くようになります。

function print_args(self_ptr, args_ptr, kwargs_ptr) result(r) bind(c, name = 'print_args')
O@HP8:~/forpy/DLL$ ifort -c -fpic ../forpy_mod.F90
O@HP8:~/forpy/DLL$ ifort -shared -fpic -o extexample01.so extexample01.f90 forpy_mod.o `python3-config --ldflags`
O@HP8:~/forpy/DLL$ python extexample01.py
Segmentation fault (core dumped)
O@HP8:~/forpy/DLL$ vi extexample01.f90
O@HP8:~/forpy/DLL$ ifort -shared -fpic -o extexample01.so extexample01.f90 forpy_mod.o `python3-config --ldflags`
O@HP8:~/forpy/DLL$ python extexample01.py
('hello', 42)
{'key': 'abc'}
3.141592653589793
O@HP8:~/forpy/DLL$

gfortran ・・・うまくゆかず

なお gfortran Ver.7 ではコンパイル時にエラーが出て実行できませんでした。

O@HP8:~/forpy/gfort5$ ls
forpy_mod.F90  forpy_mod.mod  forpy_mod.o
O@HP8:~/forpy/gfort5$ gfortran -c -fPIC ../forpy_mod.F90
O@HP8:~/forpy/gfort5$ gfortran ../intro_to_forpy.F90 forpy_mod.o `python3-config --ldflags`
lto1: internal compiler error: in lto_tag_to_tree_code, at lto-streamer.h:1005
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-7/README.Bugs> for instructions.
lto-wrapper: fatal error: gfortran returned 1 exit status
compilation terminated.
/usr/bin/x86_64-linux-gnu-ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
O@HP8:~/forpy/gfort5$ gfortran --version
GNU Fortran (Ubuntu 7.3.0-16ubuntu3~16.04.1) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

O@HP8:~/forpy/gfort5$

追記 (H30.8.17)

gfortran でうまくいかなかったのは、Python を anaconda で入れた場合の症状のようです。対処法が出ていました。たしかにうまくゆきます。

GitHub - ylikx/forpy: Forpy - use Python from Fortran

Using forpy with Anaconda
When using forpy with Anaconda and gfortran, you might encounter the following error:

/usr/bin/x86_64-linux-gnu-ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
A solution to this problem is to add the -fno-lto compiler flag in the linking step:

gfortran -c forpy_mod.F90
gfortran intro_to_forpy.F90 forpy_mod.o -fno-lto `python3-config --ldflags`

蛇はマジむかつくわw

邪神ちゃんドロップキック 邪神ちゃん 全高約135mm PVC製 塗装済み 完成品 フィギュア

邪神ちゃんドロップキック 邪神ちゃん 全高約135mm PVC製 塗装済み 完成品 フィギュア