使用 F2PY 创建 Fortran 扩展模块,自定义签名文件和子程序存储在单独的 Fortran 文件中?
Create a Fortran extension module using F2PY with a custom signature file and subroutines stored in separate Fortran files?
作为练习,我尝试创建一个 python 模块 fibadd1
,其中包含一个方法 fibadd
。此方法将吃掉一个整数并吐出前 n 个斐波那契数加上 1 的 numpy 数组(即 1、2、2、3,...)。包含此例程的 Fortran 代码是 fib2.f
,并使用包含在 fib1.f
中的子例程 FIB
。该子例程计算前 N 个斐波那契数。仅使用这两个文件,我就能够使用名为 test2.py
的 python 脚本直接从源代码成功编译给定的例程。但是,在尝试创建自定义 .pyf
签名文件(如 this tutorial 时)时,我遇到了障碍 运行。签名文件名为fib2.pyf
.
我能够从命令行使用命令 python -m numpy.f2py -c fib2.pyf fib2.f fib1.f --compiler=mingw32
成功编译和 运行 所有内容。但是,我希望能够使用 numpy.f2py.run_main(...)
和 numpy.f2py.compile(...)
函数在 python 脚本中执行此操作。基于 this documentation 看来它们应该具有相同(或相似)的功能。我试过的脚本叫做 test3.py
.
它只是在退出时给出 1。是否可以在 python 脚本中执行此操作?还有比我链接的文档更多的文档吗?我在解析 numpy.f2py.compile
函数时遇到问题。
源码如下:
fib2.f
C FILE: FIB2.F
SUBROUTINE FIBADD(A,N)
C
C ADD 1 TO THE FIBONACCI ROUTINE
C
INTEGER N
REAL*8 A(N)
CALL FIB(A, N)
DO I=1,N
A(I) = A(I) + 1.0D0
ENDDO
END
C END FILE FIB2.F
fib1.f
C FILE: FIB1.F
SUBROUTINE FIB(A,N)
C
C CALCULATE FIRST N FIBONACCI NUMBERS
C
INTEGER N
REAL*8 A(N)
DO I=1,N
IF (I.EQ.1) THEN
A(I) = 0.0D0
ELSEIF (I.EQ.2) THEN
A(I) = 1.0D0
ELSE
A(I) = A(I-1) + A(I-2)
ENDIF
ENDDO
RETURN
END
C END FILE FIB1.F
test2.py
import numpy.f2py
import numpy as np
with open('fib2.f') as file:
source = file.read()
module = 'fibadd1'
args = ['fib1.f', '--compiler=mingw32']
failure = numpy.f2py.compile(source, modulename=module,
extra_args=args, verbose=False)
print(failure)
import fibadd1
a = np.zeros(8, 'd')
fibadd1.fibadd(a)
print(a)
fib2.pyf
! -*- f90 -*-
! Note: the context of this file is case sensitive.
python module fib2
interface
subroutine fibadd(a,n)
real*8 dimension(n),intent(out),depend(n) :: a
integer intent(in) :: n
end subroutine fibadd
end interface
end python module fib2
! This file was auto-generated with f2py (version:2).
! See http://cens.ioc.ee/projects/f2py2e/
test3.py
import numpy.f2py
import numpy as np
with open('fib2.f') as file:
source = file.read()
module = 'fibadd1'
args = ['fib2.pyf','fib1.f', '--compiler=mingw32']
failure = numpy.f2py.compile(source, modulename=module,
extra_args=args, verbose=False)
print(failure)
事实证明,在修改后的 .pyf
文件中,有两行 python module fib2
和 end python module fib2
指示导入的 python 模块名称(去数字)。为了成功编译,numpy.f2py.compile
函数的 modulename
关键字必须匹配该名称。因此,更正后的.py
编译脚本为:
import numpy.f2py
with open('fib2.f') as file:
source = file.read()
module = 'fib2'
args = ['fib2.pyf','fib1.f', '--compiler=mingw32']
failure = numpy.f2py.compile(source, extra_args=args,
modulename=module, verbose=False)
print(failure)
import fib2
a = fib2.fibadd(8)
print(a)
作为练习,我尝试创建一个 python 模块 fibadd1
,其中包含一个方法 fibadd
。此方法将吃掉一个整数并吐出前 n 个斐波那契数加上 1 的 numpy 数组(即 1、2、2、3,...)。包含此例程的 Fortran 代码是 fib2.f
,并使用包含在 fib1.f
中的子例程 FIB
。该子例程计算前 N 个斐波那契数。仅使用这两个文件,我就能够使用名为 test2.py
的 python 脚本直接从源代码成功编译给定的例程。但是,在尝试创建自定义 .pyf
签名文件(如 this tutorial 时)时,我遇到了障碍 运行。签名文件名为fib2.pyf
.
我能够从命令行使用命令 python -m numpy.f2py -c fib2.pyf fib2.f fib1.f --compiler=mingw32
成功编译和 运行 所有内容。但是,我希望能够使用 numpy.f2py.run_main(...)
和 numpy.f2py.compile(...)
函数在 python 脚本中执行此操作。基于 this documentation 看来它们应该具有相同(或相似)的功能。我试过的脚本叫做 test3.py
.
它只是在退出时给出 1。是否可以在 python 脚本中执行此操作?还有比我链接的文档更多的文档吗?我在解析 numpy.f2py.compile
函数时遇到问题。
源码如下:
fib2.f
C FILE: FIB2.F
SUBROUTINE FIBADD(A,N)
C
C ADD 1 TO THE FIBONACCI ROUTINE
C
INTEGER N
REAL*8 A(N)
CALL FIB(A, N)
DO I=1,N
A(I) = A(I) + 1.0D0
ENDDO
END
C END FILE FIB2.F
fib1.f
C FILE: FIB1.F
SUBROUTINE FIB(A,N)
C
C CALCULATE FIRST N FIBONACCI NUMBERS
C
INTEGER N
REAL*8 A(N)
DO I=1,N
IF (I.EQ.1) THEN
A(I) = 0.0D0
ELSEIF (I.EQ.2) THEN
A(I) = 1.0D0
ELSE
A(I) = A(I-1) + A(I-2)
ENDIF
ENDDO
RETURN
END
C END FILE FIB1.F
test2.py
import numpy.f2py
import numpy as np
with open('fib2.f') as file:
source = file.read()
module = 'fibadd1'
args = ['fib1.f', '--compiler=mingw32']
failure = numpy.f2py.compile(source, modulename=module,
extra_args=args, verbose=False)
print(failure)
import fibadd1
a = np.zeros(8, 'd')
fibadd1.fibadd(a)
print(a)
fib2.pyf
! -*- f90 -*-
! Note: the context of this file is case sensitive.
python module fib2
interface
subroutine fibadd(a,n)
real*8 dimension(n),intent(out),depend(n) :: a
integer intent(in) :: n
end subroutine fibadd
end interface
end python module fib2
! This file was auto-generated with f2py (version:2).
! See http://cens.ioc.ee/projects/f2py2e/
test3.py
import numpy.f2py
import numpy as np
with open('fib2.f') as file:
source = file.read()
module = 'fibadd1'
args = ['fib2.pyf','fib1.f', '--compiler=mingw32']
failure = numpy.f2py.compile(source, modulename=module,
extra_args=args, verbose=False)
print(failure)
事实证明,在修改后的 .pyf
文件中,有两行 python module fib2
和 end python module fib2
指示导入的 python 模块名称(去数字)。为了成功编译,numpy.f2py.compile
函数的 modulename
关键字必须匹配该名称。因此,更正后的.py
编译脚本为:
import numpy.f2py
with open('fib2.f') as file:
source = file.read()
module = 'fib2'
args = ['fib2.pyf','fib1.f', '--compiler=mingw32']
failure = numpy.f2py.compile(source, extra_args=args,
modulename=module, verbose=False)
print(failure)
import fib2
a = fib2.fibadd(8)
print(a)