【问题标题】:Compiling f90 function that returns array using f2py使用 f2py 编译返回数组的 f90 函数
【发布时间】:2025-11-30 07:30:02
【问题描述】:

我有一个计算大数组并将其写入文件的子程序。我正在尝试将其转换为返回该数组的函数。但是,我遇到了一个非常奇怪的错误,这似乎与我返回一个数组的事实有关。当我尝试返回一个浮点数(作为测试)时,它工作得很好。

这是 MWE,我用 mwe('dir', 'postpfile', 150, 90.) 从 python 调用它:

FUNCTION mwe(dir, postpfile, nz, z_scale)
IMPLICIT NONE

INTEGER         :: nz
REAL(KIND=8)    :: z_scale
CHARACTER(len=100)      :: postpfile
CHARACTER(len=100)         :: dir
REAL(kind=8)  :: mwe

print*,'dir ', dir
print*,'postpfile ', postpfile
print*,'nz ', nz
print*,'Lz ', z_scale

mwe = 4.5d0
END FUNCTION mwe

这运行良好并且可以按预期打印:

 dir dir                                                                                                 
 postpfile postpfile                                                                                           
 nz          150
 Lz    90.000000000000000     

但是,如果我将函数定义为数组:

FUNCTION mwe(dir, postpfile, nz, z_scale)
IMPLICIT NONE

INTEGER         :: nz
REAL(KIND=8)    :: z_scale
CHARACTER(len=100)      :: postpfile
CHARACTER(len=100)         :: dir
REAL(KIND=8),DIMENSION (2,23)   :: mwe

print*,'dir ', dir
print*,'postpfile ', postpfile
print*,'nz ', nz
print*,'Lz ', z_scale

mwe = 4.5d0
END FUNCTION mwe

然后它打印这个:

 dir postpfile                                                                                           
 postpfile ��:����������k�� 2����V@(����H���;�!��v
 nz            0
Segmentation fault (core dumped)

我正在运行 f2py 版本 2、NumPy 1.11.1 和 Python 3.5.1。

编辑

我正在使用f2py -c -m fmwe fmwe.f90 进行编译,并使用mwe('dir', 'postpfile', 150, 90.) 调用该函数。

【问题讨论】:

  • @JonatanÖström 这是新问题。这样你就可以测试我的 MWE。
  • 那些代码sn-ps是一样的。
  • @ŁukaszRogalski 我的错。刚刚修好了。
  • 你是怎么解决的?你修复了什么?
  • 如果您提供您使用的f2py 命令以及显示您如何导入和使用的最小python,这可能会有所帮助。

标签: python arrays fortran f2py


【解决方案1】:

我认为问题出在缺少显式接口的地方。 (不确定可能其他人可以更准确地指出问题所在。)

尽管我不确定我的解释,但我有 2 个工作案例。 将您的函数更改为子例程将您的函数放入模块中(它自己生成显式接口)解决了您提到的问题。

下面的脚本仍然可以像my_sub('dir', 'postpfile', 150, 90.)那样从python调用。

subroutine my_sub(mwe, dir, postpfile, nz, z_scale)
implicit none

integer,intent(in)             :: nz
real(KIND=8),intent(in)        :: z_scale
chracter(len=100),intent(in)   :: postpfile
character(len=100), intent(in) :: dir
real(KIND=8), intent(out)      :: mwe(2,23)

print*,'dir ', dir
print*,'postpfile ', postpfile
print*,'nz ', nz
print*,'Lz ', z_scale

mwe = 4.5d0
end subroutine my_sub

如果你在一个模块中使用这个函数,你需要从 python 中调用一些不同的方法; test('dir', 'postpfile', 150, 90.).

module test

contains 
function mwe(dir, postpfile, nz, z_scale)
implicit none

integer            :: nz
real(KIND=8)       :: z_scale
chracter           :: postpfile
character(len=100) :: dir
real(KIND=8)       :: mwe(2,23)

print*,'dir ', dir
print*,'postpfile ', postpfile
print*,'nz ', nz
print*,'Lz ', z_scale

mwe = 4.5d0
end function mwe

end module test

我没有尝试,但它可能适用于适当的 Fortran interface,包括您的函数。(假设存在显式接口是关键)

我希望有人能完成/纠正我的答案。

【讨论】: