f2py:预分配数组作为Fortran子例程的输入

时间:2015-01-28 14:11:25

标签: python numpy fortran f2py

这是我想在python中调用的Fortran子例程的最小化片段。任务很简单。第一次调用代码时,会将值分配给数组 iwk 的第一个条目。然后第二次调用子例程,预期的行为是指定的条目不变。

subroutine testf2py (md,iwk,ndp,nip)

  implicit none

  integer ndp
!f2py intent(in) :: ndp
  integer nip
!f2py intent(in) :: nip
  integer iwk(31*ndp + nip)
!f2py intent(in) :: iwk     
  integer md
!f2py intent(in) :: md

  if ( md == 1 ) then
    iwk(1) = ndp
  end if  

  print*, iwk(1)

end

(首次通话: md = 1,后续通话: md > 1)。数组 iwk 应该在python中分配,并且数组中的值应该在两次调用之间不受影响。在Fortran中调用此函数可以正常工作:

program main
  implicit none
  integer :: i, ndp, nip  
  integer, allocatable :: iwk(:)

  ndp = 10
  nip = 10

  allocate(iwk(31*ndp+nip))  

  call test (1, iwk, ndp, nip)
  call test (2, iwk, ndp, nip)

end program main

输出2个电话:

10
10

在python中,用f2py编译子程序后,它不起作用。 iwk 中的值更改:

import testf2py
import numpy as np

ndp = 10
nip = 10

iwk = np.empty([31*ndp+nip,], dtype=int, order='F')

testf2py.test(1, iwk, ndp, nip)
testf2py.test(2, iwk, ndp, nip)

输出2个电话:

10
1686728152   

第二个数字是随机的。

我尝试以不同的方式在python中分配,np.empty_like,np.zeros。没有帮助。我认为问题在于如何分配iwk数组(因此问题标题),但不确定。我需要改变什么来使它工作?最好,我只想更改python脚本并保留Fortran代码。

1 个答案:

答案 0 :(得分:3)

告诉python数组是intent(in)

  integer iwk(31*ndp + nip)
!f2py intent(in) :: iwk  

您不得更改它,并希望保留更改。你可能想要intent(inout)

更好的是,忘记!f2py intent并直接使用:

  integer, intent(inout) :: iwk(31*ndp + nip)

如果您尝试修改intent(in)变量,编译器会告诉您错了。

小心使用Python中的正确dtype,它必须与Fortran类型相对应。大多数情况下,Fortran integer相当于int32,但有时可能是int64。您也可以在Fortran中控制它(integer*4integer(int32),...)。