Я хотів би використати f2py
сучасний Fortran. Зокрема, я намагаюся отримати наступний базовий приклад для роботи. Це найменший корисний приклад, який я міг би створити.
! alloc_test.f90
subroutine f(x, z)
implicit none
! Argument Declarations !
real*8, intent(in) :: x(:)
real*8, intent(out) :: z(:)
! Variable Declarations !
real*8, allocatable :: y(:)
integer :: n
! Variable Initializations !
n = size(x)
allocate(y(n))
! Statements !
y(:) = 1.0
z = x + y
deallocate(y)
return
end subroutine f
Зверніть увагу, що n
випливає з форми вхідного параметра x
. Зверніть увагу, що y
виділяється та розміщується в тілі підпрограми.
Коли я компілюю це f2py
f2py -c alloc_test.f90 -m alloc
А потім біжи в Python
from alloc import f
from numpy import ones
x = ones(5)
print f(x)
Я отримую таку помилку
ValueError: failed to create intent(cache|hide)|optional array-- must have defined dimensions but got (-1,)
Тож я йду і створюю та редагую pyf
файл вручну
f2py -h alloc_test.pyf -m alloc alloc_test.f90
Оригінал
python module alloc ! in
interface ! in :alloc
subroutine f(x,z) ! in :alloc:alloc_test.f90
real*8 dimension(:),intent(in) :: x
real*8 dimension(:),intent(out) :: z
end subroutine f
end interface
end python module alloc
Змінено
python module alloc ! in
interface ! in :alloc
subroutine f(x,z,n) ! in :alloc:alloc_test.f90
integer, intent(in) :: n
real*8 dimension(n),intent(in) :: x
real*8 dimension(n),intent(out) :: z
end subroutine f
end interface
end python module alloc
Тепер він працює, але значення виводу z
завжди є 0
. Деякі налагодження друку виявляють, що n
має значення 0
в підпрограмі f
. Я припускаю, що мені не вистачає якоїсь f2py
магії заголовків, щоб правильно керувати цією ситуацією.
Більш загально, який найкращий спосіб зв’язати вищевказану підпрограму в Python? Я настійно вважаю за краще не змінювати саму підпрограму.