我需要用f2py包装一个简单的fortran90代码.fortran模块"test.f90"是
module util
contains
FUNCTION gasdev(idum)
implicit none
INTEGER(kind=4), intent(inout) :: idum
REAL(kind=8) :: gasdev, ran2
print*,idum
gasdev = ran2(idum)
return
END FUNCTION
FUNCTION ran2(idum)
implicit none
INTEGER(kind=4), intent(inout) :: idum
REAL(kind=8) :: ran2
print*,idum
ran2=2.D0
return
END FUNCTION
end module util
Run Code Online (Sandbox Code Playgroud)
然后我用它包装
f2py -m test -c test.f90
Run Code Online (Sandbox Code Playgroud)
但是当我在python中导入它时
In [2]: import test
Run Code Online (Sandbox Code Playgroud)
它提示我说错误
ImportError: ./test.so: undefined symbol: ran2_
Run Code Online (Sandbox Code Playgroud)
关于如何修复它的任何想法?谢谢.
我在 Windows 7 下使用 Python 3.2。我的 Python 脚本需要一些数值子例程,我想用 Fortran 编写它们并使用 f2py 使它们与我的脚本兼容。
根据f2py 文档,我安装了 numpy (v1.6.1),然后尝试f2py在命令行上运行来检查安装。Windows 不断告诉我“f2py 不被识别为内部或外部命令、可操作程序或批处理文件”。我尝试将“C:\Python32\Scripts”添加到我的路径中,但这没有帮助。(C:\Python32是我的Python安装目录,也在我的PATH中,numpy也安装在这里)
我究竟做错了什么?
背景:
我的程序目前在 Python 中组装数组。这些数组连接到前端 UI,因此具有交互元素(即用户在数组元素中指定的值)。然后将这些数组保存到 .txt 文件中(取决于它们以后的用途)。然后,用户必须离开 Python 程序并运行一个单独的 Fortran 脚本,该脚本根据 Python 输出文件模拟系统。虽然这最多只需要几分钟,但我理想情况下希望自动化该过程,而无需离开我的 Python UI。
组装数组 (Python) ->编辑数组 (Python) ->导出到文件 (Python)
->导入文件 (Fortran) ->运行模拟 (Fortran) ->将结果导出到文件 (Fortran)
->将文件导入到 UI,显示图表 (Python)
问题:
这可能吗?我有哪些选项可以自动化此过程?我可以完全删除文件的重复导出/导入吗?
编辑: 我还应该提到 fortran 脚本使用 Lapack,我不知道这是否有区别。
我编写了一个小型 Fortran 函数,并使用 f2py 在 Python 中向它传递参数。不知怎的,参数的顺序在传输过程中被搞乱了,我不明白为什么。
Fortran 函数的相关部分(位于名为 calc_密度.f95 的文件中):
subroutine calc_density(position, nparticles, ncells, L, density)
implicit none
integer, intent(in) :: nparticles
integer, intent(in) :: ncells
double precision, intent(in) :: L
double precision, dimension(nparticles), intent(in) :: position
double precision, dimension(ncells), intent(out) :: density
double precision :: sumBuf, offSum
integer :: pLower, pUpper, pBuf, numBuf, last, idx
double precision, dimension(nparticles) :: sorted
print *, 'Fortran ', 'position length ', size(position), &
'density length ', size(density), 'nparticles ', nparticles, &
'ncells …Run Code Online (Sandbox Code Playgroud) 当我调用以下函数时,它会1按预期返回:
integer function my_func() result(myresult)
myresult = 1
end function my_func
Run Code Online (Sandbox Code Playgroud)
但是,当我将返回值的名称修改为以字母“ r”开头时,该函数将返回0。
integer function my_func() result(rresult)
rresult = 1
end function my_func
Run Code Online (Sandbox Code Playgroud)
是什么原因造成的?我的第一个想法是,它与隐式类型有关,但该函数位于指定的模块中implicit none。
这是完整的模块
module my_mod
implicit none
contains
integer function my_func() result(myresult)
myresult = 1
end function my_func
end module my_mod
Run Code Online (Sandbox Code Playgroud)
我正在使用Fortran 90并使用gfortran进行编译。
编辑
这是演示该问题的完整程序
生成文件:
.PHONY: pytest clean
CYTHON_LIB = fortran_mods.cpython-37m-x86_64-linux-gnu.so
FFLAGS += -fdefault-real-8
pytest: $(CYTHON_LIB)
./tests.py
$(CYTHON_LIB): my_mod.F90
f2py -c -m fortran_mods my_mod.F90 --f90flags="$(FFLAGS)"
clean:
rm *.so
Run Code Online (Sandbox Code Playgroud)
my_mod.F90:
module …Run Code Online (Sandbox Code Playgroud) 嗨,我是用f2py包裹LAPACK例行dgesvd,通过编译dgesvd.f文件和链接它反对llapack,如解释在这里
根据文档字符串,dgesvd 模块具有签名:
dgesvd - Function signature:
dgesvd(jobu,jobvt,m,n,a,s,u,vt,work,lwork,info,[lda,ldu,ldvt])
Required arguments:
jobu : input string(len=1)
jobvt : input string(len=1)
m : input int
n : input int
a : input rank-2 array('d') with bounds (lda,*)
s : input rank-1 array('d') with bounds (*)
u : input rank-2 array('d') with bounds (ldu,*)
vt : input rank-2 array('d') with bounds (ldvt,*)
work : input rank-1 array('d') with bounds (*)
lwork : input int
info : input int
Optional arguments:
lda := shape(a,0) …Run Code Online (Sandbox Code Playgroud) 我似乎无法使用 f2py 创建模块来将数字传回 python 时保持双精度。一个最小的例子,带有文件 fmodules.f90:
subroutine example(output)
implicit none
double precision :: output
cf2py intent(out) :: output
output = 1.3
end subroutine example
Run Code Online (Sandbox Code Playgroud)
然后我使用 f2py 创建模块:
$ f2py -c -m fmodules fmodules.f90
Run Code Online (Sandbox Code Playgroud)
并从 python 中调用它:
>>> from fmodules import example
>>> example()
1.2999999523162842
Run Code Online (Sandbox Code Playgroud)
根据我的计算,精度约为 8 位数字。我的印象是双精度应该给出大约 16。我已经尝试了我能想到的所有排列,包括处理文件.f2py_f2cmap。对我所缺少的有什么想法吗?
我有一个简单的fortran子程序(仅用于测试python-fortran接口).它看起来像这样:
subroutine sum2(x,y,z)
real(kind=8),intent(in)::x,y
real(kind=8),intent(inout)::z
z = x + y
print *, "sum is ", z
end subroutine sum2
Run Code Online (Sandbox Code Playgroud)
编译后f2py我去python并执行以下操作:
>>> import sum2
>>> x = 1.0
>>> y = 2.0
>>> z = 0.0
>>> sum2.sum2(x,y,z)
sum is 3
>>> z
0.0
Run Code Online (Sandbox Code Playgroud)
因此,即使z指定为inout,其值也不会被函数更改.我需要知道原因.另一个问题涉及notebook.如果我sum2在那里导入并运行sum2.sum2(x,y,z)我甚至看不到消息sum is ....那么,问题是,如果可以在笔记本中调用fortran子程序吗?
编辑
有一个合理的评论,在我的例子中,我使用了不可变的数据类型.所以,我决定改变它,但我仍然有同样的问题.所以,我的新fortran子程序看起来像这样:
subroutine arr(x)
real(kind=8),dimension(1)::x
x(1) = 2 ! new value
print *, "x[0] …Run Code Online (Sandbox Code Playgroud) 很抱歉对 Fortran 90 和 f2py 都不熟悉。
我使用的是 Windows 64 位、Python 3.4 64 位、gfortran。Numpy 版本是 1.9.1,我在 gnu.py 中评论了“raise NotImplementedError("Only MS compiler supported with gfortran on win64")”,如以下链接所示:http ://scientificcomputingco.blogspot.com.au /2013/02/f2py-on-64bit-windows-python27.html
我在 fortran 中有一个模块,编写如下,带有模块范围变量dp:
! testf2py.f90
module testf2py
implicit none
private
public dp, i1
integer, parameter :: dp=kind(0.d0)
contains
real(dp) function i1(m)
real(dp), intent(in) :: m(3, 3)
i1 = m(1, 1) + m(2, 2) + m(3, 3)
return
end function i1
end module testf2py
Run Code Online (Sandbox Code Playgroud)
然后,如果我跑 f2py -c testf2py.f90 -m testf2py
它会报告错误,指出未声明 …
为了在 python2 中使用 f2py 构建扩展模块,我一直在使用类似于以下内容的 Makefile:
default: fortran_lib.so
%.so:: %.f90
f2py -c -m $* $<
Run Code Online (Sandbox Code Playgroud)
为了完整起见,这里还有一个虚拟fortran_lib.f90文件
subroutine square(d)
implicit none
!f2py intent(inout) d
integer, intent(inout) :: d
d = d*d
end subroutine square
Run Code Online (Sandbox Code Playgroud)
这曾经工作正常,make只会产生fortran_lib.so.
现在我也想支持 python3,但是在使用时f2py3,make会生成版本号fortran_lib.cpython-35m-x86_64-linux-gnu.so(在我的特定设置中)。
由于这与指定的目标名称不同,make因此无法识别目标已经创建。因此,每次运行时它都会重新制作目标make。
我如何解决这个问题(无需对版本进行硬编码)?
distutils,...)?