我想制作这样的文件,以便在python中使用它.如何从fortran源创建共享库?
我测试过如下代码.
gfortran -c mod.f90
#gfortran -c sub1.f90
gfortran -c func.f90
gfortran -shared -fPIC -o func.so func.f90 mod.o
Run Code Online (Sandbox Code Playgroud)
但是我无法在python中导入它.我在fortran源代码中使用了模块文件.我从python导入了fortran源代码.我不确定我做对了.
[===>14:47:59]f1:python
Python 2.7.2+ (default, Oct 4 2011, 20:03:08)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import func
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initfunc)
func.f90
-----------------------------------------
program func
use mod_test
switch1 = .true.
switch2 = .false.
x = 1.2
!call test(x, …Run Code Online (Sandbox Code Playgroud) 我有一个python脚本,我希望大致这样做:
将一些粒子位置调用到数组中
在所有512 ^ 3个位置上运行算法以将它们分配到NxNxN矩阵
将该矩阵反馈给python
使用python中的绘图来可视化矩阵(即mayavi)
首先我必须连续编写它,但理想情况下我想并行化第2步以加速计算.什么工具/策略可能会让我开始.我知道Python和Fortran很好但不太关于如何将这两个连接到我的特定问题.目前我正在Fortran中完成所有工作,然后加载我的python程序 - 我想立刻完成所有工作.我听说过py2f,但是在我走下一个特定的兔子洞之前,我希望得到经验丰富的人的意见.谢谢
编辑:我想要平行的东西是"令人尴尬的平行",因为它只是一个N粒子循环,我想尽快通过这个循环.
当我调用f2py包装函数时,Global Interpretter Lock(GIL)是否会被释放?
(我很高兴尝试自己发现,但我对numpy来源不太熟悉,知道从哪里开始寻找)......
为了澄清,对这个问题的一个好的答案要么帮助我知道在numpy来源中寻找a的位置,Py_BEGIN_ALLOW_THREADS 或者它只是让我知道GIL是否被释放(最好有一些证据).
使用F2PY作为包装器,是否可以将子例程与子例程调用一起使用?如果是这样,怎么办?
如果我不清楚,我的意思是这样的:
SUBROUTINE average(a, b, out)
real a, b, out
cf2py intent(in) a, b
cf2py intent(out) out
call add(a, b, out)
out=out/2
END
Run Code Online (Sandbox Code Playgroud)
add子例程如下:
subroutine add(a, b, out)
real a, b, out
out = a + b
return
end
Run Code Online (Sandbox Code Playgroud)
尝试f2py -c -m average average.f并导入到python我得到:
ImportError:./average.so:未定义的符号:add_
另外,将意图添加到第二个子例程中也无法解决该问题。
我有一个这个简单的Fortran代码(stack.f90):
subroutine fortran_sum(f,xs,nf,nxs)
integer nf,nxs
double precision xs,result
dimension xs(nxs),result(nf)
external f
result = 0.0
do I = 1,nxs
result = result + f(xs(I))
print *,xs(I),f(xs(I))
enddo
return
end
Run Code Online (Sandbox Code Playgroud)
我正在编译使用:
f2py -c --compiler=mingw32 -m stack2 stack2.f90
Run Code Online (Sandbox Code Playgroud)
然后使用这个Python脚本(stack.py)进行测试:
import numpy as np
from numpy import cos, sin , exp
from stack import fortran_sum
def func(x):
return x**2
if __name__ == '__main__':
xs = np.linspace(0.,10.,10)
ans = fortran_sum(func,xs,1)
print 'Fortran:',ans
print 'Python:',func(xs).sum()
Run Code Online (Sandbox Code Playgroud)
当我使用"python stack.py"它时,它会给出:
0.0000000000000000 0.00000000 …Run Code Online (Sandbox Code Playgroud) 我用f2py包装了一些fortran代码.这是fortran代码:
MODULE iteration
implicit none
contains
SUBROUTINE iterate(alpha, beta, e, es, rank, omega, smearing, prec, max_step)
REAL(kind=8), INTENT(in) :: omega, smearing, prec
INTEGER :: max_step, step, rank, cnt
COMPLEX(kind=16) :: alpha(rank,rank), beta(rank,rank), omega_mat(rank, rank), green(rank, rank)
COMPLEX(kind=16), INTENT(inout) :: e(rank,rank), es(rank,rank)
step = 0
omega_mat = 0
DO cnt=1, rank
omega_mat(cnt, cnt) = 1.0
ENDDO
omega_mat = omega_mat * (omega + (0.0, 1.0) * smearing)
DO WHILE (minval(abs(alpha)) .gt. prec .or. minval(abs(beta)) .gt. prec .and. step .lt. max_step)
green = …Run Code Online (Sandbox Code Playgroud) 如果我打算将一个布尔值 NumPy 数组传递给 Fortran 变量,应该如何输入它们f2py?我已经尝试了integer*1和logical*1,但是这两个都表明该数组已被复制。
例如,如果我编译文件foo.f95,包含:
subroutine foo(x, n)
logical*1 x(n)
!f2py intent(in) x
!f2py intent(hide), depend(x) :: n=shape(x,0)
...
end subroutine
Run Code Online (Sandbox Code Playgroud)
使用f2py -c -m foo foo.f90 -DF2PY_REPORT_ON_ARRAY_COPY=1并运行以下内容:
import numpy as np
import foo
x = np.random.randn(100) < 0
foo.foo(x)
Run Code Online (Sandbox Code Playgroud)
它打印
copied an array: size=100, elsize=1
Run Code Online (Sandbox Code Playgroud)
如果我更改logical*1为integer*1. Fortran 文件中布尔数组的正确类型是什么,以便不复制数组?
请注意,这不是内存连续性的问题,因为数组是一维的——foo.foo(np.asfortranarray(x))打印相同的复制消息。
我正在研究分形生成器代码。主要代码是用Python编写的,迭代部分是用Fortran编写的。我使用f2py将两个代码粘合在一起。这是我使用的 fortran 函数:
function iterate(z0, func, zmax, niter) result(n)
implicit none
complex(kind=8), intent(in) :: z0
real(kind=8), intent(in) :: zmax
integer, intent(in) :: niter
external func
complex(kind=8) :: func
integer :: n
complex(kind=8) :: z
n = 0
z = z0
do while ((n < niter) .and. (abs(z) < zmax))
z = func(z)
n = n + 1
end do
end function iterate
Run Code Online (Sandbox Code Playgroud)
这是生成的包装器代码的文档字符串:
n = iterate(z0,func,zmax,niter,[func_extra_args])
Wrapper for ``iterate``.
Parameters
----------
z0 : input complex
func : call-back …Run Code Online (Sandbox Code Playgroud) 我已经使用 Fortran 90 一段时间了,最近决定使用 f2py 封装一些模块,以使用 Python 作为前端来简化原型设计。
\n\n但是,在尝试编译传递外部函数(来自 Python)的子例程时,我遇到了错误。这是复制错误的代码:
\n\n! file: callback.f90\nsubroutine callback(f,x,y)\n implicit none\n ! - args -\n ! in\n external :: f\n real(kind=kind(0.0d0)), intent(in) :: x\n ! out\n real(kind=kind(0.0d0)), intent(inout) :: y\n\n y = f(x)\nend subroutine\nRun Code Online (Sandbox Code Playgroud)\n\n现在,如果我使用 f2py 生成签名文件 (.pyf),我将获得以下结果:
\n\n! -*- f90 -*- \n! Note: the context of this file is case sensitive.\npython module callback__user__routines \ninterface callback_user_interface \n function f(x) result (y) ! in :callback:callback.f90\n intent(inout) f\n real(kind=kind(0.0d0)) intent(in) :: x\n real(kind=kind(0.0d0)) …Run Code Online (Sandbox Code Playgroud) 我定义了一个 Fortran 连续数组:
import numpy as np
hp = np.zeros([number_fragments, max(length_fragments_list), 6], order='F')
Run Code Online (Sandbox Code Playgroud)
该数组的切片在 Fortran 中不是连续的。我该如何解决这个问题?
hn = hp[0,0:Length-1,:]
hn.flags
C_CONTIGUOUS : False
F_CONTIGUOUS : False
also
hn = hp[0,0:Length-1,:].copy()
hn.flags
C_CONTIGUOUS : True
F_CONTIGUOUS : False
Run Code Online (Sandbox Code Playgroud)
如何在切片后轻松获得 Fortran 连续数组?