numpy - 当子例程包含内部过程时,f2py 给出错误(但使用 gfortran 编译成功)

标签 numpy fortran gfortran f2py

以下程序在子例程不包含任何内部过程时编译(在 f2py 中)但在包含任何内部过程时无法在 f2py 中编译(使用 gfortran 编译)

Fortran 代码:

subroutine example(array)
    implicit none
    real*8::array(:,:)
    INTEGER::i,j
!f2py intent(inout)::array

    do i=1,3
        do j=1,3
            array(i,j)=10*i+j
        enddo
        ! print*,''
    enddo
    call tentimes(array)
    RETURN

    contains

    subroutine tentimes(array)
        implicit none
!f2py intent(inout):array
        real*8::array(:,:)
        array=array*10
    end subroutine tentimes



end subroutine example



program dummy
    implicit none
    
end program dummy

使用 python -m numpy.f2py -c allocate.f90 -m ftest 编译

和 python 代码:

import numpy as np

a=np.zeros((3,3),order="F")

print(a)
res=ftest.example(a)
print(a)

为什么会这样?

f2py 产生的错误:

compiling Fortran sources
Fortran f77 compiler: /usr/bin/gfortran -Wall -g -ffixed-form -fno-second-underscore -fPIC -O3 -funroll-loops
Fortran f90 compiler: /usr/bin/gfortran -Wall -g -fno-second-underscore -fPIC -O3 -funroll-loops
Fortran fix compiler: /usr/bin/gfortran -Wall -g -ffixed-form -fno-second-underscore -Wall -g -fno-second-underscore -fPIC -O3 -funroll-loops
compile options: '-I/tmp/tmpwd_qygau/src.linux-x86_64-3.9 -I/home/srj/.local/lib/python3.9/site-packages/numpy/core/include -I/usr/include/python3.9 -c'
gfortran:f90: allocate.f90
allocate.f90:17:31:

   17 |     subroutine tentimes(array_i)
      |                               1
Warning: Unused dummy argument ‘array_i’ at (1) [-Wunused-dummy-argument]
allocate.f90:17:23:

   17 |     subroutine tentimes(array_i)
      |                       ^
Warning: ‘tentimes’ defined but not used [-Wunused-function]
gfortran:f90: /tmp/tmpwd_qygau/src.linux-x86_64-3.9/ftest-f2pywrappers2.f90
/tmp/tmpwd_qygau/src.linux-x86_64-3.9/ftest-f2pywrappers2.f90:13:17:

   13 |                 subroutine tentimes(array_i)
      |                 1
Error: Unclassifiable statement at (1)
/tmp/tmpwd_qygau/src.linux-x86_64-3.9/ftest-f2pywrappers2.f90:15:39:

   15 |                 end subroutine tentimes
      |                                       1
Error: Expected label ‘example’ for END SUBROUTINE statement at (1)
/tmp/tmpwd_qygau/src.linux-x86_64-3.9/ftest-f2pywrappers2.f90:14:53:

   14 |                     real*8, dimension(:,:) :: array_i
      |                                                     1
Error: Array ‘array_i’ at (1) cannot have a deferred shape
error: Command "/usr/bin/gfortran -Wall -g -fno-second-underscore -fPIC -O3 -funroll-loops -I/tmp/tmpwd_qygau/src.linux-x86_64-3.9 -I/home/srj/.local/lib/python3.9/site-packages/numpy/core/include -I/usr/include/python3.9 -c -c /tmp/tmpwd_qygau/src.linux-x86_64-3.9/ftest-f2pywrappers2.f90 -o /tmp/tmpwd_qygau/tmp/tmpwd_qygau/src.linux-x86_64-3.9/ftest-f2pywrappers2.o" failed with exit status 1

类似的嵌套过程在 gfortran 中运行良好。为什么会出现这个错误?如何纠正这个问题?

最佳答案

编辑:使用 f2py 的更好方法是“the smart way

这样做效果很好

python -m numpy.f2py allocate.f90 -m ftest -h ftest.pyf && \
python -m numpy.f2py -c ftest.pyf allocate.f90

因为这会绕过生成 FORTRAN 接口(interface)。


好的,我确认是f2py的bug,f2pywrappers2.f90中生成的代码有错误

f2py 产生:

!     -*- f90 -*-
!     This file is autogenerated with f2py (version:1.21.2)
!     It contains Fortran 90 wrappers to fortran functions.

      subroutine f2pywrapexample (array, f2py_array_d0, f2py_array_d1)
      integer f2py_array_d0
      integer f2py_array_d1
      real*8 array(f2py_array_d0,f2py_array_d1)
      interface
      
            subroutine example(array) 
                real*8, dimension(:,:),intent(inout) :: array
                subroutine tentimes(array) 
                    real*8, dimension(:,:) :: array
                end subroutine tentimes
            end subroutine example
      end interface
      call example(array)
      end

正确代码:

      subroutine f2pywrapexample (array, f2py_array_d0, f2py_array_d1)
      integer f2py_array_d0
      integer f2py_array_d1
      real*8 array(f2py_array_d0,f2py_array_d1)
      interface
      
            subroutine example(array) 
                real*8, dimension(:,:),intent(inout) :: array
            end subroutine example
            subroutine tentimes(array) 
                real*8, dimension(:,:) :: array
            end subroutine tentimes
      end interface
      call example(array)
      end

接口(interface)实际上不应该包含嵌套过程,即使子例程有嵌套过程

解决这个问题,然后生成相应的对象,将其放在正确的临时文件夹中并手动链接到命令

/usr/bin/gfortran -Wall -g -Wall -g -shared /tmp/tmpfw0ammli/tmp/tmpfw0ammli/src.linux-x86_64-3.9/ftestmodule.o /tmp/tmpfw0ammli/tmp/tmpfw0ammli/src.linux-x86_64-3.9/fortranobject.o /tmp/tmpfw0ammli/allocate.o /tmp/tmpfw0ammli/tmp/tmpfw0ammli/src.linux-x86_64-3.9/ftest-f2pywrappers2.o -L/usr/lib/gcc/x86_64-redhat-linux/11 -L/usr/lib/gcc/x86_64-redhat-linux/11 -L/usr/lib64 -lgfortran -o ./ftest.cpython-39-x86_64-linux-gnu.so

这成功了,python 打印出正确的输出。

enter image description here

关于numpy - 当子例程包含内部过程时,f2py 给出错误(但使用 gfortran 编译成功),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69537576/

相关文章:

fortran - FORTRAN 中的字符串操作 : strange behavior

python - np.array 中特定长度的连续部分的 Min-Max 差异

c++ - 尝试将我的 C++ 可执行文件与 Fortran 库(Cygwin 环境)链接起来

python - 在 python numpy 中构建一个 nxn 矩阵,对于任何 n

fortran - 通过 fftw_mpi_r2c_2d 和 fftw_mpi_c2r_2d 输出不正确

linux - IMSL 和 MPI 之间的冲突

fortran - 访问主程序子目录中的文件

fortran - 第一列中的 "d"标签,Fortran 77

python - 遍历numpy中的任意维度

python - 在 numpy.einsum 中对省略号广播维度求和