Mi piacerebbe usare f2pycon il moderno Fortran. In particolare, sto cercando di far funzionare il seguente esempio di base. Questo è il più piccolo esempio utile che potrei generare.
! 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
Si noti che nè dedotto dalla forma del parametro di input x. Si noti che yè allocato e deallocato all'interno del corpo della subroutine.
Quando lo compilo con f2py
f2py -c alloc_test.f90 -m alloc
E poi esegui in Python
from alloc import f
from numpy import ones
x = ones(5)
print f(x)
Ottengo il seguente errore
ValueError: failed to create intent(cache|hide)|optional array-- must have defined dimensions but got (-1,)
Quindi vado a creare e modificare il pyffile manualmente
f2py -h alloc_test.pyf -m alloc alloc_test.f90
Originale
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
Modificata
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
Ora funziona ma i valori dell'output zsono sempre 0. Alcune stampe di debug rivelano che nha il valore 0all'interno della subroutine f. Presumo che mi manchi un po 'di f2pymagia dell'intestazione per gestire correttamente questa situazione.
Più in generale, qual è il modo migliore per collegare la subroutine sopra in Python? Preferirei fortemente non dover modificare la subroutine stessa.