gpt4 book ai didi

python - 用 Cython 包装一个 f2py 编译的 Fortran .so(不通过 python)

转载 作者:太空宇宙 更新时间:2023-11-04 06:05:51 26 4
gpt4 key购买 nike

看看其他一些类似的问题 ( Cython and fortran - how to compile together without f2py ),我可能会以错误的方式解决这个问题,但我想实现的工作流程似乎是如此 cythonic/pythonic,如果以下内容我会感到惊讶不可能:

1) 使用包含我需要的 foo 子例程的 fortran_func.f 源文件中的 f2py 编译一个 fortran_func.so。由于我有 .f 源,所以我知道正确的函数调用语法。

2) 魔法步骤可能涉及“cdef extern”或类似的东西。

3) 无需直接调用函数:

import fortran_func

out = fortran_func.foo(x, y)

我的想法是围绕这个函数调用我有三个 for 循环,并且通过 python 导入调用 fortran 函数真的很慢。目前我有这个:

import fortran_func

cdef np.ndarray[double, ndim=3] cy_func(double[::1] x,
double[::1] y,
double[::1] z,
int N):
cdef:
int i, j, k
np.ndarray[double, ndim=3] out

out = np.zeros((N, N, N), dtype=np.float64)

for i in range(N): # fast C loops
for j in range(N):
for k in range(N):
# extremely slow python call
out[i,j,k] = fortran_func.foo(x[i], y[j], z[k])

# would prefer a fast, direct function call
# out[i,j,k] = foo(x[i], y[j], z[k])

如果您能帮助我找出这个神奇的步骤应该是什么,我将不胜感激!

最佳答案

您可以使用 ctypes 将共享的 fortran 对象作为 c 函数调用,而无需转换为 python 类型。你也应该能够用 cython 做到这一点。我写在这里:

http://pythology.blogspot.fr/2014/03/wrapping-fortran-and-python-without-f2py.html

这是总结:

fortran 文件 add.f95:

subroutine add(a,b,c)    
implicit none
integer a,b,c
c = a + b
end

编译:

gfortran -shared -fPIC add.f95 -o add.so

调用它的 python 代码(小心,'add' 变成了 'add_')是:

#!/usr/bin/env python

from ctypes import c_int, byref, cdll

a = c_int(3)
b = c_int(4)
c = c_int()

addlib = cdll.LoadLibrary('./add.so')
addlib.add_(byref(a),byref(b),byref(c))
print c

关于python - 用 Cython 包装一个 f2py 编译的 Fortran .so(不通过 python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22142411/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com