python - 编译 forpy 以在 Fortran 中调用 Python 对象

标签 python compiler-errors fortran gfortran

我的问题
我意识到需要在我的项目中实现从 Fortran 到 Python 的正式连接(上下文如下),我的场景似乎是 f2py 的完美场景。或 forpy .我选择 forpy 是因为它似乎更适合从 Fortran 调用 Python,这在 f2py 中似乎更难。

我克隆了 git 存储库并浏览了入门部分,但在编译 forpy_mod.F90 时遇到了一个奇怪的错误(粘贴在下面)。有谁知道此错误的原因/修复方法?

  • 在 linux 机器上使用 python 3.8.8 运行 miniconda
  • [编辑:] 使用 GNU Fortran (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

可能不必要的上下文:
我正在使用一个基于 Fortran 的大型轨道软件,该软件由数千个 Fortran 子例程组成。我的任务是在这些子例程之一中调用 python 代码,然后调用 Python API,该 API 已被简化为将单个值返回给 Fortran 程序。这个序列将在单次轨道运行中发生数万到数十万次。

我已经使用 Fortran 的 EXECUTE_COMMAND_LINE() 函数成功地实现了这两个程序之间的连接,但是 Python 代码本身有很多开销,当从命令行调用时,它会重新导入每次调用函数时都会打包(其中有很多)。这会导致极长的运行时间(按天数排序,而使用默认值应该只需要大约 6 分钟)。我已经尽我所能减少了 Python API 的开销。

尝试编译 forpy 时出错

 $ gfortran -c forpy_mod.F90

forpy_mod.F90:1924.54:

  character(kind=C_CHAR, len=:), pointer :: doc_string
                                                      1
Error: Deferred-length character component 'doc_string' at (1) is not yet supported
forpy_mod.F90:1961.54:

  character(kind=C_CHAR, len=:), pointer :: doc_string
                                                      1
Error: Deferred-length character component 'doc_string' at (1) is not yet supported
forpy_mod.F90:1961.54:

  character(kind=C_CHAR, len=:), pointer :: doc_string
                                                      1
Error: Deferred-length character component 'doc_string' at (1) is not yet supported
forpy_mod.F90:11788.12:

  m = c_loc(self%methods)
            1
Error: Argument 'self' to 'c_loc' at (1) must be an associated scalar POINTER
forpy_mod.F90:9581.41:

      flag = strcmp(buffer_format, c_loc(format_code))
                                         1
Error: CHARACTER argument 'format_code' to 'c_loc' at (1) must have a length of 1
forpy_mod.F90:9586.43:

        flag = strcmp(buffer_format, c_loc(format_code))
                                           1
Error: CHARACTER argument 'format_code' to 'c_loc' at (1) must have a length of 1
forpy_mod.F90:9595.41:

      flag = strcmp(buffer_format, c_loc(format_code))
                                         1
Error: CHARACTER argument 'format_code' to 'c_loc' at (1) must have a length of 1
forpy_mod.F90:9600.43:

        flag = strcmp(buffer_format, c_loc(format_code))
                                           1
Error: CHARACTER argument 'format_code' to 'c_loc' at (1) must have a length of 1
forpy_mod.F90:9606.43:

        flag = strcmp(buffer_format, c_loc(format_code))
                                           1
Error: CHARACTER argument 'format_code' to 'c_loc' at (1) must have a length of 1
forpy_mod.F90:9613.37:

  flag = strcmp(buffer_format, c_loc(format_c_string))
                                     1
Error: CHARACTER argument 'format_c_string' to 'c_loc' at (1) must have a length of 1
forpy_mod.F90:9292.24:

  buffer%format = c_loc(format_c_string)
                        1
Error: CHARACTER argument 'format_c_string' to 'c_loc' at (1) must have a length of 1
forpy_mod.F90:9186.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:9102.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:9018.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8934.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8850.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8766.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8682.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8598.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8514.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8430.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8346.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8262.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8178.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:8094.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
Fatal Error: Error count reached limit of 25.

最佳答案

您使用的编译器版本不支持代码中使用的多个功能。您应该使用更新的编译器版本或不同的编译器(或避免使用这些功能)。

这里有两个不同的方面要看。

首先:


  character(kind=C_CHAR, len=:), pointer :: doc_string
                                                      1
Error: Deferred-length character component 'doc_string' at (1) is not yet supported
forpy_mod.F90:1961.54:

编译器在这里非常明确地说“我知道你的代码很好,但我不知道如何处理它。然而。”这个“尚未支持”是寻找更高版本编译器的重要提示。

派生类型的延迟长度字符组件是 Fortran 2003 的一项功能,但直到 gfortran 4.9 才支持此功能,即使语法已被理解。

第二个:

  buffer%format = c_loc(format_c_string)
                        1
Error: CHARACTER argument 'format_c_string' to 'c_loc' at (1) must have a length of 1
forpy_mod.F90:9186.51:

  ierror = ndarray_create_nocopy_helper(res, c_loc(array), shape(array, kind=PY
                                                   1
Error: Assumed-shape array 'array' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable
forpy_mod.F90:9102.51:

编译器在这里以一种稍微不同的方式提示。虽然我们的第一个案例是“我知道你的代码很好,但我不知道如何处理它”。这里我们有“你的代码是错误的,我没有按照你的要求去做。”

Fortran 是一种不断发展的语言。随着延迟长度字符的添加(并作为派生类型的一个组件可用),限制可能会随着语言的不同而变化。

Fortran 2003 c_loc 通常要求其参数是 C 语言可互操作的。根据 Fortran 2003 解释,假定形状数组不能作为 c_loc 的参数,长度不为 1 的字符也不能。Fortran 2008 放宽了对 c_loc 的限制参数:对于此代码,您需要一个编译器来实现 Fortran 2008(或更高版本)中的规则,而不是 Fortran 2003 中的规则。

关于python - 编译 forpy 以在 Fortran 中调用 Python 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68839565/

相关文章:

linux - g77 版本 3.2 使用选项 -finit-local-zero 创建大目标文件

python - 使用 sklearn 的 PCA

python - SqlAlchemy 中单独的 REST 请求的单独 session 对象?

python - SciPy 警告消息 : "Ill-conditioned matrix detected"

python - 如何在python中使用for语句创建数千个变量

c++ - 我怎样才能克服 "unsafe"错误?

ruby - 我该如何解决这个关于 end 关键字的 Ruby 语法错误?

c++ - 错误到底是什么以及错误地为可 move 和不可复制成员调用复制构造函数有什么解决方法

macos - 在 Mac 上从 Fortran 编译 'static' 二进制文件

performance - 调用接口(interface)函数比直接调用成员函数更快?