【问题标题】:Why can't a subroutine with assumed-shape argument have an internal function?为什么具有假定形状参数的子程序不能具有内部功能?
【发布时间】:2020-04-20 19:30:34
【问题描述】:

我有一个带有假定形状数组的子例程,其中还包含一个内部函数:

subroutine test(x)
   real x(:)
contains
   function a()
   end
end

当我尝试使用 f2py (f2py -c test.f90 -m test) 编译它时,会打印以下错误:

gfortran:f77: /tmp/tmphb_l9bkr/src.linux-x86_64-3.7/test-f2pywrappers.f
/tmp/tmphb_l9bkr/src.linux-x86_64-3.7/test-f2pywrappers.f:11:10:

           function a() ! in :test:test.f90:test
          1
Error: Unclassifiable statement at (1)
/tmp/tmphb_l9bkr/src.linux-x86_64-3.7/test-f2pywrappers.f:13:13:

           end function a
             1
Error: Expecting END SUBROUTINE statement at (1)

但是,如果我删除了内部函数a(),或者为数组指定了一个明确的形状(例如real x(5)),它编译得很好。上面给出的代码有什么问题?

【问题讨论】:

  • 欢迎您,请拨打tour。当您使用end function 时会发生什么?它曾经是必需的。您应该报告您的编译器版本并尝试最新版本。
  • 上述代码sn-p和报错不一致。生成上述错误时,您能否发布您正在使用的实际代码。我还注意到字符 f77 表明这被视为 Fortran 77,其中不存在包含的函数,假设您实际使用的代码与您发布的代码相差不大,这将解释上述错误。我不知道 f2py,但这可能是 3 年前卡住了,假设 Fortran 77,
  • @IanBush 实际上,代码似乎与错误消息一致。那是因为代码经过 f2py 预处理器。

标签: python numpy fortran f2py


【解决方案1】:

情况似乎很奇怪。为了更确定在end function a 错误消息的推动下发生了什么,我添加了完整的结束语句

subroutine test(x)
   real x
contains
   function a()
   end function a
end subroutine test

正如您在错误消息中看到的,gfortran 错误并非来自您的原始源代码,而是来自/tmp/ 目录中的不同源代码。如果你打开它,它看起来像这样:

C     -*- fortran -*-
C     This file is autogenerated with f2py (version:2)
C     It contains Fortran 77 wrappers to fortran functions.

      subroutine f2pywraptest (x, f2py_x_d0)
      integer f2py_x_d0
      real x(f2py_x_d0)
      interface
      subroutine test(x) 
          real, dimension(:) :: x
          function a() ! in :nestedf:nestedf.f90:test
          end function a
      end subroutine test
      end interface
      call test(x)
      end

它是一个用于调用您的子例程的包装器。这样做的原因是为了让 Python 更容易调用您的代码,而无需 Python 理解假定的形状参数。但是f2py在创建接口时并没有正确理解内部函数。

很遗憾,您必须做出选择。您可以使用假定的形状参数,也可以使用内部函数。但是 f2py 两者都不理解。或者您必须以某种方式拦截 f2py 临时文件并修复它,然后再继续,但我不知道该怎么做。

我不会对包装源中提到的 Fortran 77 分心。它们可能意味着包装器本身可以在没有显式接口的情况下调用,并且源文件是固定格式的。但它显然包含 Fortran 90 功能。

【讨论】:

    猜你喜欢
    • 2017-12-26
    • 2021-02-21
    • 2011-06-23
    • 2021-06-14
    • 2020-01-09
    • 2020-09-11
    • 2016-06-08
    • 1970-01-01
    相关资源
    最近更新 更多