Numpy: [BUG] f2py no puede compilar el módulo de extensión si primero se generan las fuentes C

Creado en 22 nov. 2019  ·  7Comentarios  ·  Fuente: numpy/numpy

Siguiendo los documentos / Guía del usuario de f2py, si uno quiere generar un archivo .c con el módulo de extensión, debe hacerlo

$ f2py -m fib1 fib1.f

para generar un archivo fib1module.c . Esto funciona. Sin embargo, el siguiente paso para construir el módulo de extensión para que sea importable en Python, según los documentos, es

$ f2py -c fib1module.c

Sin embargo, esto me falla con los siguientes mensajes:

$ f2py -c fib1module.c --verbose
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building extension "untitled" sources
build_src: building npy-pkg config files
running build_ext
new_compiler returns <class 'distutils.unixccompiler.UnixCCompiler'>
customize UnixCCompiler
customize UnixCCompiler using build_ext
********************************************************************************
<class 'distutils.unixccompiler.UnixCCompiler'>
preprocessor  = ['gcc', '-pthread', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-Wl,--sysroot=/', '-E']
compiler      = ['gcc', '-pthread', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-Wl,--sysroot=/', '-Wsign-compare', '-DNDEBUG', '-g', '-fwrapv', '-O3', '-Wall', '-Wstrict-prototypes', '-std=c99']
compiler_so   = ['gcc', '-pthread', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-Wl,--sysroot=/', '-Wsign-compare', '-DNDEBUG', '-g', '-fwrapv', '-O3', '-Wall', '-Wstrict-prototypes', '-fPIC', '-std=c99']
compiler_cxx  = ['g++', '-pthread', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-Wl,--sysroot=/']
linker_so     = ['gcc', '-pthread', '-shared', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-L/opt/miniconda/envs/numpy-dev/lib', '-Wl,-rpath=/opt/miniconda/envs/numpy-dev/lib', '-Wl,--no-as-needed', '-Wl,--sysroot=/']
linker_exe    = ['gcc', '-pthread', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-Wl,--sysroot=/']
archiver      = ['ar', 'rc']
ranlib        = None
libraries     = []
library_dirs  = []
include_dirs  = ['/opt/miniconda/envs/numpy-dev/include/python3.6m']
********************************************************************************
building 'untitled' extension
compiling C sources
C compiler: gcc -pthread -B /opt/miniconda/envs/numpy-dev/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -std=c99

compile options: '-I/home/melissa/projects/numpy/numpy/core/include -I/opt/miniconda/envs/numpy-dev/include/python3.6m -c'
gcc: fib1module.c
fib1module.c:16:10: fatal error: fortranobject.h: Arquivo ou diretório inexistente
   16 | #include "fortranobject.h"
      |          ^~~~~~~~~~~~~~~~~
compilation terminated.
error: Command "gcc -pthread -B /opt/miniconda/envs/numpy-dev/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -std=c99 -I/home/melissa/projects/numpy/numpy/core/include -I/opt/miniconda/envs/numpy-dev/include/python3.6m -c fib1module.c -o /tmp/tmpyjgu4iq5/fib1module.o -MMD -MF /tmp/tmpyjgu4iq5/fib1module.o.d" failed with exit status 1

Haciendo

$ f2py -c fib1module.c -I/home/melissa/projects/numpy/numpy/f2py/src -m fib1module

parece funcionar (esta es la ubicación de mi archivo fortranobject.h ), pero entonces el módulo no se puede importar:

>>> import fib1module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /home/melissa/projects/numpy/doc/source/f2py/fib1module.cpython-36m-x86_64-linux-gnu.so: undefined symbol: PyFortran_Type

TL; DR: ¿Es esto un error o algo que se supone que no debemos hacer (generar fuentes .c y luego construir el módulo de extensión en un paso separado)?

>>> import sys, numpy; print(numpy.__version__, sys.version)
1.18.0.dev0+8d217b0 3.6.7 | packaged by conda-forge | (default, Jul  2 2019, 02:18:42) 
[GCC 7.3.0]
00 - Bug numpy.f2py

Comentario más útil

No estoy seguro de qué documentos dicen esto, pero lo siguiente es incorrecto:

$ f2py -c fib1module.c

f2py -c ... debe aplicarse al archivo .pyf (más los archivos fuente / objeto / biblioteca) o se debe especificar la opción -m <modulename> (más los archivos fuentes / objeto / biblioteca) . f2py -c no está destinado a compilar los módulos de extensión C / API generados directamente (aunque es probable que pueda hacerlo con los indicadores del directorio de inclusión adecuados y las entradas del archivo fuente / objeto).

Utilice una de las siguientes opciones:

f2py -c -m fib1 fib1.f

o

f2py -m fib1 fib1.f -h fib1.pyf
f2py -c fib1.pyf fib1.f

Estos ejemplos son mínimos en el sentido de que si se omite algo en las líneas de comando f2py anteriores, se espera una falla.

Todos 7 comentarios

Gracias por el informe @melissawm. Estamos hablando de esta página, ¿verdad: https://numpy.org/devdocs/f2py/getting-started.html?

Puedo confirmar lo que estás viendo:

$ f2py -m fib1 fib1.f
$ f2py -c fib1module.c
...
fib1module.c:16:10: fatal error: 'fortranobject.h' file not found
#include "fortranobject.h"

Sin embargo, la página del documento hace $ f2py -c -m fib1 fib1.f lugar (genera código y compílalo de una vez), y eso funciona como se esperaba para mí. No estoy seguro de si alguna vez se admitió la separación de -m y -c . Debería ser posible hacer que -c -only funcione, agregando automáticamente la ruta de inclusión correcta; probablemente no sea difícil, pero no estoy seguro de si es necesario.

@pearu ¿ algún pensamiento?

No estoy seguro de qué documentos dicen esto, pero lo siguiente es incorrecto:

$ f2py -c fib1module.c

f2py -c ... debe aplicarse al archivo .pyf (más los archivos fuente / objeto / biblioteca) o se debe especificar la opción -m <modulename> (más los archivos fuentes / objeto / biblioteca) . f2py -c no está destinado a compilar los módulos de extensión C / API generados directamente (aunque es probable que pueda hacerlo con los indicadores del directorio de inclusión adecuados y las entradas del archivo fuente / objeto).

Utilice una de las siguientes opciones:

f2py -c -m fib1 fib1.f

o

f2py -m fib1 fib1.f -h fib1.pyf
f2py -c fib1.pyf fib1.f

Estos ejemplos son mínimos en el sentido de que si se omite algo en las líneas de comando f2py anteriores, se espera una falla.

En realidad, estoy hablando de esta página: https://numpy.org/devdocs/f2py/usage.html

Allí, en los elementos 2 y 3, tenemos lo siguiente: El elemento 2 es ejecutar f2py sin las opciones -m o -c , que aparentemente no funciona. El artículo 3 dice

Para construir un módulo de extensión, use

f2py -c <options> <fortran files>       \
  [[ only: <fortran functions>  : ]     \
   [ skip: <fortran functions>  : ]]... \
  [ <fortran/c source files> ] [ <.o, .a, .so files> ]

Si <fortran files> contiene un archivo de firma, entonces se construye una fuente para un módulo de extensión,
Se compilan todas las fuentes de Fortran y C y, finalmente, todos los archivos de objetos y bibliotecas están vinculados al
módulo de extensión <modulename>.so que se guarda en el directorio actual.

Si <fortran files> no contiene un archivo de firma, entonces se construye un módulo de extensión por
escaneando todos los códigos fuente de Fortran en busca de firmas de rutina.

Por lo que dijiste, entiendo que se supone que no debemos usar las fuentes .c directamente, ¿verdad? Si generamos un archivo .c , ¿es inutilizable más adelante?

¡Gracias por el aporte!

En realidad, estoy hablando de esta página: https://numpy.org/devdocs/f2py/usage.html

Esta página describe las opciones de la línea de comandos f2py y los diferentes modos. Se supone que uno comprende cómo se pueden construir los módulos de extensión de Python; consulte, por ejemplo, https://docs.python.org/3.8/extending/index.html

Mientras que f2py se puede usar para crear módulos de extensión que envuelvan también funciones C (contenidas en archivos .c ) y por lo tanto, la declaración "no se supone que usemos las fuentes .c directamente" es inexacta.

Uno debe distinguir los archivos .c que genera f2py y los archivos .c que contienen implementaciones de usuario de funciones C. El archivo .c que genera f2py es útil solo cuando se necesita tener un control total de cómo se construye el módulo de extensión o para depurar f2py. En todos los demás casos, no es necesario generar el módulo de extensión, ya que se generará automáticamente en el proceso de construcción.

Estoy agregando la explicación de @pearu anterior a los documentos, si tiene alguna otra idea, hágamelo saber. ¡Gracias a todos por sus comentarios!

No dude en cerrar el problema (¿o debería hacerlo solo después de que se acepte el RP?)

Sugiero cerrar cuando se acepte el RP que aborde este tema.

Sugiero cerrar cuando se acepte el RP que aborde este tema.

+1

@melissawm también puede agregar closes gh-14960 a uno de sus mensajes de confirmación, luego el problema se cierra automáticamente cuando el PR se fusiona.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

kevinzhai80 picture kevinzhai80  ·  4Comentarios

dcsaba89 picture dcsaba89  ·  3Comentarios

navytux picture navytux  ·  4Comentarios

marcocaccin picture marcocaccin  ·  4Comentarios

Kreol64 picture Kreol64  ·  3Comentarios