Je voudrais utiliser f2py
avec le Fortran moderne. En particulier, j'essaie de faire fonctionner l'exemple de base suivant. Ceci est le plus petit exemple utile que j'ai pu générer.
! 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
Notez que cela n
est déduit de la forme du paramètre d'entrée x
. Notez que y
est alloué et désalloué dans le corps du sous-programme.
Quand je compile cela avec f2py
f2py -c alloc_test.f90 -m alloc
Et puis exécutez en Python
from alloc import f
from numpy import ones
x = ones(5)
print f(x)
J'obtiens l'erreur suivante
ValueError: failed to create intent(cache|hide)|optional array-- must have defined dimensions but got (-1,)
Je vais donc créer et éditer le pyf
fichier manuellement
f2py -h alloc_test.pyf -m alloc alloc_test.f90
Original
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
Modifié
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
Maintenant, il s'exécute mais les valeurs de la sortie z
sont toujours 0
. Une impression de débogage révèle que cela n
a de la valeur 0
dans le sous-programme f
. Je suppose qu'il me manque une f2py
magie d'en-tête pour gérer correctement cette situation.
Plus généralement, quelle est la meilleure façon de lier le sous-programme ci-dessus à Python? Je préférerais fortement ne pas avoir à modifier le sous-programme lui-même.