我想设置一个工作流,在Windows机器上使用Cython从Python访问fortran例程
经过一番搜索,我发现: http://www.fortran90.org/src/best-practices.html#interfacing-with-c和https://stackoverflow.com/tags/fortran-iso-c-binding/info
还有一些代码图片:
Fortran方面:
pygfunc.h:
void c_gfunc(double x, int n, int m, double *a, double *b, double *c);
pygfunc.f90型
^{pr2}$gfunc.f90
module gfunc_module
use iso_c_binding
implicit none
contains
subroutine gfunc(x, a, b, c)
real, intent(in) :: x
real, dimension(:), intent(in) :: a, b
real, dimension(:,:), intent(out) :: c
integer :: i, j, n, m
n = size(a)
m = size(b)
do j=1,m
do i=1,n
c(i,j) = exp(-x * (a(i)**2 + b(j)**2))
end do
end do
end subroutine
end module
Cython侧边:
在pygfunc.pyx公司在
cimport numpy as cnp
import numpy as np
cdef extern from "./pygfunc.h":
void c_gfunc(double, int, int, double *, double *, double *)
cdef extern from "./pygfunc.h":
pass
def f(float x, a=-10.0, b=10.0, n=100):
cdef cnp.ndarray ax, c
ax = np.arange(a, b, (b-a)/float(n))
n = ax.shape[0]
c = np.ndarray((n,n), dtype=np.float64, order='F')
c_gfunc(x, n, n, <double *> ax.data, <double *> ax.data, <double *> c.data)
return c
以及安装文件:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
ext_modules = [Extension('pygfunc', ['pygfunc.pyx'])]
setup(
name = 'pygfunc',
include_dirs = [np.get_include()],
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules )
所有文件都在一个目录中
fortran文件编译(使用NAG fortran Builder)pygfunc编译
但是把它们联系起来会引发一个:
错误LNK2019:引用了未解析的外部符号 在函数\uu pyx_pf_7pyfunc_f中
当然还有:
致命错误LNK1120:1个未解析的外部
我错过了什么?或者,这种在Python和Fortran之间建立工作流的方法从一开始就是该死的?在
泰铢 马丁
下面是一个最小的工作示例。 我使用了gfortran并将编译命令直接写入安装文件。在
gfunc.f90
^{pr2}$pygfunc.f90
pygfunc.h
pygfunc.pyx
setup.py
test.py
我所做的大多数改变都不是很根本。以下是一些重要的。在
你混合了双精度和单精度浮点数。别那样做。同时使用real(Fortran)、float(Cython)和float32(NumPy),并同时使用double precision(Fortran)、double(Cyton)和float64(NumPy)。不要无意中把它们混在一起。我想让你成为我的榜样。
您应该将所有变量作为指针传递给Fortran。在这方面,它与C调用约定不符。Fortran中的iso_c_绑定模块只与c命名约定匹配。将数组作为指针传递,其大小作为单独的值。也许还有别的办法,但我不知道。
我还在安装文件中添加了一些内容,以显示在构建时可以在哪里添加一些更有用的额外参数。在
要编译,请运行
python setup.py build_ext inplace
。要验证它是否有效,请运行测试脚本。在下面是fortran90.org上显示的示例:mesh_exp
这里还有两个我不久前放在一起的:ftridiag,fssor 我当然不是这方面的专家,但这些例子可能是一个很好的起点。在
相关问题 更多 >
编程相关推荐