Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当使用f2py时,fortran模块内的函数范围与为fortran程序编译时的不同?_Python_Fortran90_Gfortran_F2py - Fatal编程技术网

Python 当使用f2py时,fortran模块内的函数范围与为fortran程序编译时的不同?

Python 当使用f2py时,fortran模块内的函数范围与为fortran程序编译时的不同?,python,fortran90,gfortran,f2py,Python,Fortran90,Gfortran,F2py,我的问题是,当使用f2py编译时,模块中定义的函数无法识别某些模块变量。如果声明传递给函数的变量类型的参数(例如描述实类型的变量或维度元素),则会引发错误。使用gfortran编译时,我没有遇到此错误。有什么区别?在使用f2py编译时,如何纠正这些错误 我的示例文件,moddata.f90,包含以下代码: module mod implicit none integer, parameter :: dp = selected_real_kind(15) integer, para

我的问题是,当使用f2py编译时,模块中定义的函数无法识别某些模块变量。如果声明传递给函数的变量类型的参数(例如描述
类型的变量或维度元素),则会引发错误。使用gfortran编译时,我没有遇到此错误。有什么区别?在使用f2py编译时,如何纠正这些错误

我的示例文件,
moddata.f90
,包含以下代码:

module mod

  implicit none

  integer, parameter :: dp = selected_real_kind(15)
  integer, parameter :: nelem = 3
  real(kind=dp), dimension(nelem) :: b

  parameter (b=(/3,1,2/))

contains
  function foo(x,y) result(z)
!  dp, nelem are defined in module above
    real(kind=dp), intent(in) :: x !scalar
    integer, dimension(nelem), intent(in) :: y
!  local variable
    real(kind=dp) :: z

    z = sum(b*y*x)

  end function foo
end module mod
我用

f2py -c -m moddata moddata.f90
我得到了这些错误:

  y_Dims[0]=(nelem);
             ^
1 warning and 1 error generated.reduce to a constant expression
如果我在
整数、维度(nelem)、意图(in)::y
之前重新定义
整数、参数::nelem=3
,然后重新编译,我得到

      real(kind=dp) foof2pywrap
                1
Error: Parameter 'dp' at (1) has not been declared or is a variable, which does not reduce to a constant expression
每个
real(kind=dp)
声明都有相同的错误,并且

      foof2pywrap = foo(x, y)
                    1
Warning: Possible change of value in conversion from REAL(8) to REAL(4) at (1)
因此,我必须通过函数中的
integer,parameter::dp=selected\u real\u kind(15)
重新定义
dp
。然后它就起作用了


当我用fortran包装器编译这个模块时,我没有遇到这些错误。我想知道为什么函数中的
nelem
dp
没有用f2py正确限定范围?

也许我错了,但我认为f2py不能处理
模块
+
包含Fortran 90的
功能。如果您将代码转换为

function foo(x,y) result(z)
   integer, parameter :: dp = selected_real_kind(15)
   real(kind=dp), intent(in) :: x
   integer, parameter :: nelem = 3
   integer, dimension(3), parameter :  = (/3, 1, 2/)
   integer, dimension(nelem), intent(in) :: y
   real(kind=dp) :: z

   z = sum(b*y*x)
end function
并像以前一样编译它,它可以工作:

 >>> x = 1.0000000000
 >>> y = [2, 3, 4]
 >>> moddata.foo(x,y)
 17.0

编辑

答案是f2py不理解如何将Fortran函数转换为python函数。因此,我将
函数foo
更改为
子例程foo2
,然后编译为
f2py moddata.f90-m moddata
,并作为输出

Reading fortran codes...
        Reading file 'moddata.f90' (format:free)
Post-processing...
        Block: moddata
                        Block: moddata
In: :moddata:moddata.f90:moddata
get_parameters: got "invalid syntax (<string>, line 1)" on '(/3, 1, 2/)'
                                Block: foo2
Post-processing (stage 2)...
        Block: moddata
                Block: unknown_interface
                    Block: moddata
                            Block: foo2
Building modules...
        Building module "moddata"...
                Constructing F90 module support for "moddata"...
                    Variables: nelem b dp
                    Constructing wrapper function "moddata.foo2"...
getctype: "real(kind=dp)" is mapped to C "float" (to override define dict(real = dict(dp="<C typespec>")) in /home/jdwood/Documents/Physics/Fortran/tests/f2py/.f2py_f2cmap file).
getctype: "real(kind=dp)" is mapped to C "float" (to override define dict(real = dict(dp="<C typespec>")) in /home/jdwood/Documents/Physics/Fortran/tests/f2py/.f2py_f2cmap file).
getctype: "real(kind=dp)" is mapped to C "float" (to override define dict(real = dict(dp="<C typespec>")) in /home/jdwood/Documents/Physics/Fortran/tests/f2py/.f2py_f2cmap file).
getctype: "real(kind=dp)" is mapped to C "float" (to override define dict(real = dict(dp="<C typespec>")) in /home/jdwood/Documents/Physics/Fortran/tests/f2py/.f2py_f2cmap file).
getctype: "real(kind=dp)" is mapped to C "float" (to override define dict(real = dict(dp="<C typespec>")) in /home/jdwood/Documents/Physics/Fortran/tests/f2py/.f2py_f2cmap file).
getctype: "real(kind=dp)" is mapped to C "float" (to override define dict(real = dict(dp="<C typespec>")) in /home/jdwood/Documents/Physics/Fortran/tests/f2py/.f2py_f2cmap file).
                          z = foo2(x,y)
Wrote C/API module "moddata" to file "./moddatamodule.c"
Fortran 90 wrappers are saved to "./moddata-f2pywrappers2.f90"
我不知道该怎么办。然而,当我使用
x=1.0
y=(/3,6,2/)
(使用python和Fortran程序中的模块)时,我得到了18个答案


简而言之,在使用f2py时完全避免使用函数。

我认为这不正确。这里有使用模块的示例:和。我还只包含了一个小示例,但我需要从许多函数和子例程中访问模块参数,而不仅仅是简化示例中所示的
foo
。此外,我还对文本进行了编辑,以便更清楚地说明,如果我在函数中为
dp
nelem
添加额外声明,然后它工作,所以模块+包含表单确实工作。@跛足的lambda就像我说的,“也许我错了”,但我可能已经找到了一些东西。马上更新我的答案。不,没关系,没什么。不过我会再挖掘一点。谢谢你挖掘这些信息。实际上,只要我在函数中定义了
nelem
dp
,就可以让函数运行,而无需将其转换为子例程。我可以访问
b
,而无需重新定义它。充其量,这种行为是不可预测的。事实证明,f2py有点令人失望。
analyzeline: Failed to evaluate '/3.e0+1j*( 1.e0+1j*( 2.e0/)'. Ignoring: invalid syntax (<string>, line 1)