目录
Fortran(Formula Translation)是世界上第一个被正式推广使用的高级语言,其目前仍然是数值计算领域最重要的编程语言之一,虽然有julia,python等语言兴起,但在传统的工程计算领域如有限元、大规模并行计算等,Fortran积累了丰富的被实际工程验证了的经典算法和代码,这些代码没有被改写成其他语言的必要,最好的方式是混编,而python的第三方库numpy就提供了2种调用Fortran代码的方式
- 利用numpy中的f2py
- 利用numpy中的ctypeslib和python基础库ctypes
本文记录的是第一种方式,即利用numpy中的f2py实现对fortran程序的调用,第二种方式下篇再讲。
1、运行环境
- 运行平台:windows 10
- 编译器:mingw-w64
- 下载链接1:Downloads - MinGW-w64
- 下载链接2:mingw-w64-install.exe
- 提取码:c8z7
- 注意:mingw-w64下载完成后,记得将gfortran.exe和gcc.exe文件所在的路径添加到系统环境变量,例如在我的电脑上这个路径为:D:\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin
- python环境:我的电脑上的用来测试的是python3.7.11,并且安装了numpy
2、测试实例
参考了numpy中文网中可分配数组的例子,Fortran代码allocarr.f90如下:
module mod
real, allocatable, dimension(:,:) :: b
contains
subroutine foo
integer k
if (allocated(b)) then
print*, "b=["
do k = 1,size(b,1)
print*, b(k,1:size(b,2))
enddo
print*, "]"
else
print*, "b is not allocated"
endif
end subroutine foo
end module mod
若使用例子中给到的编译命令:
f2py -c -m allocarr allocarr.f90
会在当前fortran文件目录下产生一个以pyd后缀结尾的文件(python动态库文件)和一个名为allocarr/.lib的文件目录,目录中有一个名字一大长串的以dll结尾的动态链接库
此时直接import allocarr时,提示找不到指定的模块
但将dll文件复制到pyd相同路径下,运行就成功了!
这样用起来很不方便,每次需要用到编译产生的库时,必须同时打包两个文件,并且还不能给dll文件改名,改名后也会提示找不动指定的动态库,如果编译后只会产生一个*.pyd文件多方便,在网上各种查资料,发现只要编译时指定c和fortran的编译器就行,如下
没指定编译器的话不仅产生了.pyd还会产生.dll
f2py -c allocarr.f90 -m allocarr
指定编译器后,只会生成一个.pyd文件,但在别的机器上可能没法运行
参考:https://stackoverflow.com/questions/9756212/creating-distributable-windows-python-module-with-f2py
f2py -c --fcompiler=gnu95 --compiler=mingw32 allocarr.f90 -m allocarr
f2py -c --help-compiler 查看当前系统可用的c和c++编译器
f2py -c --help-fcompiler 查看当前系统可用的Fortran编译器-static-libgcc 将gcc作为静态库
-static-libgfortran 将gfortran作为静态库
f2py -c --fcompiler=gnu95 --compiler=mingw32 --link-static-libgcc --link-static-libgfortran allocarr.f90 -m allocarr
使用如下命令后,即在当前Fortran文件目录下产生了单个的*.pyd文件,并且在没有安装mingw-64环境下的机器上运行也能成功!!!
f2py -c --fcompiler=gnu95 --compiler=mingw32 --link-static-libgcc --link-static-libgfortran allocarr.f90 -m allocarr
至此大功告成!!!下一节我将记录下numpy.ctypeslib调用fortran踩过的坑!!!
3、参考文章
人工智能 Python笔记(一)——利用F2PY调用Fortran函数或子程序https://www.dazhuanlan.com/juanpeaceandjoy/topics/1018954
f2py编译fortran程序(windows)https://zhuanlan.zhihu.com/p/372037523