子例程参数未从Python正确传递到Fortran
我正在使用f2py编译一个数字模块,供Python脚本使用。我已将我的代码简化为以下最小示例: fd.f: 时间f:子例程参数未从Python正确传递到Fortran,python,fortran,f2py,Python,Fortran,F2py,我正在使用f2py编译一个数字模块,供Python脚本使用。我已将我的代码简化为以下最小示例: fd.f: 时间f: subroutine itimes(th) use fd implicit none real(dp) th write(*,*) 'th - it',th call lprsmf(th) end subroutine itimes reprun.py: import it th = 200 it.itimes(th) import it th =
subroutine itimes(th)
use fd
implicit none
real(dp) th
write(*,*) 'th - it',th
call lprsmf(th)
end subroutine itimes
reprun.py:
import it
th = 200
it.itimes(th)
import it
th = 200
it.itime.itimes(th)
用于编译和运行的命令如下(请注意,我在Windows下使用的是cmd
):
输出为:
th - it 1.50520876326836550E-163
th - fd 1.50520876326836550E-163
我的第一个猜测是th
在某种程度上没有从reprun.py
正确地传递到子例程itimes
。但是,我不理解这种行为,因为完整版本的代码包含其他输入,所有输入都正确传递。从Fortran调用itimes时,我无法让它执行相同的操作,因此我假设它与Python/Fortran接口有关。有人能提供这种行为发生的原因吗
编辑:将reprun.py中的th=200
替换为th=200.0
将产生以下输出:
th - it 1.19472349365371216E-298
th - fd 1.19472349365371216E-298
将itimes子例程也包装到模块中。以下是我所做的: itimes.f90:
module itime
contains
subroutine itimes(th)
use fd
implicit none
real(dp) th
write(*,*) 'th - it',th
call lprsmf(th)
end subroutine itimes
end module
编译并运行:
gfortran -c fd.f90
c:\python27_w32\python.exe c:\python27_w32\scripts\f2py.py -c -m it --compiler=mingw32 fd.f90 itimes.f90
运行reprun.py:
import it
th = 200
it.itimes(th)
import it
th = 200
it.itime.itimes(th)
输出:
th - it 200.00000000000000
th - fd 200.00000000000000
我对Python或f2py一无所知,但如果将th=200替换为th=200.0会发生什么?@HighPerformanceMark,请参见编辑。它仍然是一个垃圾值,但却是另一个。谢谢,这非常有用。再仔细研究一下,我发现我不需要itimes中的模块声明。f,似乎关键点是将fd.f90而不是fd.o传递给f2py。你知道为什么吗?@astay13啊,你可能是对的,我只是习惯性地改变了这一点。不确定,我只尝试将实际的Fortran源代码传递给f2py。我还建议始终将代码包装在模块中,这样可以避免许多Fortran陷阱。@astay13--您需要传递源代码而不是.o文件。基本上,f2py是一个fortran解析器(外加一点),它用C代码和python API包装fortran代码。然后,它将整个内容编译成一个共享对象(使用系统上可以找到的任何编译器),该对象可以由python加载。如果给f2py一个对象文件——它还不够复杂,无法对已经编译好的代码进行反向工程并生成python接口。@mgilson,我一直在用Fortran对象文件编译代码,在遇到这个问题之前,它已经正常工作了一段时间。我认为这与以下事实有关:这是我第一次尝试将
real
参数传递到主子程序中。