python numpy fortran90 f2py

python - f2py: Exponiendo parámetros de módulos "usados"



numpy fortran90 (1)

He encontrado una solución temporal a este problema, pero no es óptima. Continuaré trabajando a través de la fuente f2py para poder entenderlo mejor y solucionar el problema dentro del propio código. Hasta entonces, esta es mi solución que se inspiró en el comentario de chatcannon sobre el tema que publiqué en el github de nympy .

Hay varias formas de abordar este problema desde un punto de vista temporal, incluidas algunas formas de modificar los archivos .pyf. No quiero tener que modificar los archivos .pyf, ya que se vuelve muy incómodo como parte de un paquete más grande. Para evitar esto, agregué directivas f2py a mi fuente f90.

Tomando el ejemplo de mi pregunta original:

MODULE test INTEGER, PARAMETER :: a = 1 END MODULE test MODULE test2 USE test INTEGER, PARAMETER :: b = 2 END MODULE test2

simplemente agregue una directiva f2py en test2 para mostrar f2py cómo definir test2.a :

MODULE test INTEGER, PARAMETER :: a = 1 END MODULE test MODULE test2 USE test !f2py integer, parameter :: a ! THIS EXPOSES `a` in `test2` INTEGER, PARAMETER :: b = 2 END MODULE test2

Importar desde el test.so resultante, test.so expone test2.a correctamente:

In [1]: import test In [2]: print test.test.a 1 In [3]: print test.test.b --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) .../test_solution/<ipython-input-3-798b14f59815> in <module>() ----> 1 print test.test.b AttributeError: b In [4]: print test.test2.a 1 In [5]: print test.test2.b 2

Supongo que esta pregunta se ha abordado en algún lugar, pero he pasado una cantidad excesiva de tiempo buscando la respuesta, incluida la búsqueda un poco del código fuente. He tratado de poner el problema en el primer párrafo. El resto muestra un ejemplo básico del problema.

Estoy intentando compilar un módulo que contiene una instrucción USE que apunta a otro módulo más general. Preferiría mantener el módulo usado separado para que pueda usarse en varios "paquetes" como un conjunto de configuraciones generales. Cuando compilo los dos módulos usando f2py, todo funciona como se anuncia desde el lado de fortran, pero desde el lado de python, el USE parece ignorarse. Si permito que f2py genere un archivo de firma, el archivo contiene una declaración USE según corresponda, pero si completo la compilación e importo desde la biblioteca resultante, los parámetros del módulo usado no están disponibles en el módulo que contiene la declaración de uso. A continuación se presentan dos módulos que ilustran la situación:

MODULE test INTEGER, PARAMETER :: a = 1 END MODULE test MODULE test2 USE test INTEGER, PARAMETER :: b = 2 END MODULE test2

Para mostrar el paso intermedio ejecuté f2py -h test.pyf test.f90 test2.f90 . Se genera el siguiente archivo de firma; tenga en cuenta que el módulo "test2" contiene "use test":

! -*- f90 -*- ! Note: the context of this file is case sensitive. python module test ! in interface ! in :test module test ! in :test:test.f90 integer, parameter,optional :: a=1 end module test module test2 ! in :test:test2.f90 use test integer, parameter,optional :: b=2 end module test2 end interface end python module test ! This file was auto-generated with f2py (version:2). ! See http://cens.ioc.ee/projects/f2py2e/

Si ahora compilo con f2py --fcompiler=gfortran -c test.pyf test.f90 test2.f90 (igual que ejecutando f2py --fcompiler=gfortran -m test -c test.f90 test2.f90 sin crear el archivo de firma primero). Importar desde esta biblioteca en python expone test.test.a y test.test2.b, pero no expone test.test2.a como se puede ver aquí:

In [1]: import test In [2]: print test.test.a 1 In [3]: print test.test2.b 2 In [4]: print test.test2.a --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /users/solbrig/svn_checkouts/inversion/satmet/branches/solbrig/rootpath/data/users /GeoIPS/src/test/<ipython-input-4-bffcf464e408> in <module>() ----> 1 print test.test2.a AttributeError: a

Para ilustrar que b se define correctamente en test2 desde la perspectiva de fortran, el siguiente código usa test2 e imprime b y b :

SUBROUTINE run_test() USE test2 IMPLICIT NONE print *, "a = ", a print *, "b = ", b END SUBROUTINE run_test

Después de compilar con "f2py -m run_test -c test.f90 test2.f90 run_test.f90" y obtener run_test.so, run_test se puede importar en python y funciona como se espera:

In [1]: import run_test In [2]: run_test.run_test() a = 1 b = 2

Cualquier ayuda con este problema sería muy apreciada.

TL; DR : cuando f2py compila un módulo F90 que contiene un USE , no expone los parámetros definidos en el módulo "usado" como atributos en Python.