Ich möchte f2py
mit modernen Fortran verwenden. Insbesondere versuche ich, das folgende grundlegende Beispiel zum Laufen zu bringen. Dies ist das kleinste nützliche Beispiel, das ich generieren konnte.
! 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
Beachten Sie, dass dies n
aus der Form des Eingabeparameters abgeleitet wird x
. Beachten Sie, dass dies y
im Hauptteil der Unterroutine zugewiesen und freigegeben wird.
Wenn ich das mit kompiliere f2py
f2py -c alloc_test.f90 -m alloc
Und dann in Python ausführen
from alloc import f
from numpy import ones
x = ones(5)
print f(x)
Ich erhalte den folgenden Fehler
ValueError: failed to create intent(cache|hide)|optional array-- must have defined dimensions but got (-1,)
Also erstelle und bearbeite ich die pyf
Datei manuell
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
Geändert
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
Jetzt läuft es aber die Werte der Ausgabe z
sind immer 0
. Bei einigen Debug-Druckvorgängen wird angezeigt, dass n
der Wert 0
innerhalb der Unterroutine liegt f
. Ich gehe davon aus, dass mir etwas Kopfzauber fehlt f2py
, um diese Situation richtig zu handhaben.
Allgemeiner gesagt, was ist der beste Weg, um die obige Subroutine mit Python zu verknüpfen? Ich würde es nachdrücklich vorziehen, das Unterprogramm selbst nicht ändern zu müssen.