Numpy: [BUG] f2py ne peut pas compiler le module d'extension si les sources C sont générées en premier

Créé le 22 nov. 2019  ·  7Commentaires  ·  Source: numpy/numpy

En suivant la documentation / le guide de l'utilisateur de f2py, si l'on veut générer un fichier .c avec le module d'extension, il faut faire

$ f2py -m fib1 fib1.f

pour générer un fichier fib1module.c . Cela marche. Cependant, la prochaine étape pour construire le module d'extension pour qu'il soit importable en Python, selon la documentation, est

$ f2py -c fib1module.c

Cependant, cela échoue pour moi avec les messages suivants:

$ 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

Faire

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

semble fonctionner (c'est l'emplacement de mon fichier fortranobject.h ), mais le module n'est pas importable:

>>> 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: Est-ce un bogue ou quelque chose que nous ne sommes pas censés faire (générer des sources .c puis construire le module d'extension dans une étape séparée)?

>>> 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

Commentaire le plus utile

Je ne sais pas quels documents disent cela, mais ce qui suit est faux:

$ f2py -c fib1module.c

f2py -c ... doit être appliqué soit au fichier .pyf existant (plus les fichiers source / objet / bibliothèque) ou il faut spécifier l'option -m <modulename> (plus les fichiers sources / objet / bibliothèque) . f2py -c n'est pas destiné à compiler directement les modules d'extension C / API générés (bien qu'il soit probablement capable de le faire avec les indicateurs de répertoire d'inclusion appropriés et les entrées du fichier source / objet).

Utilisez l'une des options suivantes:

f2py -c -m fib1 fib1.f

ou

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

Ces exemples sont minimes dans le sens où si quelque chose est ignoré dans les lignes de commande f2py ci-dessus, un échec est attendu.

Tous les 7 commentaires

Merci pour le rapport @melissawm. Nous parlons de cette page à droite: https://numpy.org/devdocs/f2py/getting-started.html?

Je peux confirmer ce que vous voyez:

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

Cependant, la page doc fait $ f2py -c -m fib1 fib1.f place (génère du code et le compile en une seule fois), et cela fonctionne comme prévu pour moi. Je ne sais pas si la séparation de -m et -c a déjà été prise en charge. Il devrait être possible de faire fonctionner -c -only, en ajoutant automatiquement le bon chemin d'inclusion - probablement pas difficile, mais je ne sais pas si c'est nécessaire.

@pearu des pensées?

Je ne sais pas quels documents disent cela, mais ce qui suit est faux:

$ f2py -c fib1module.c

f2py -c ... doit être appliqué soit au fichier .pyf existant (plus les fichiers source / objet / bibliothèque) ou il faut spécifier l'option -m <modulename> (plus les fichiers sources / objet / bibliothèque) . f2py -c n'est pas destiné à compiler directement les modules d'extension C / API générés (bien qu'il soit probablement capable de le faire avec les indicateurs de répertoire d'inclusion appropriés et les entrées du fichier source / objet).

Utilisez l'une des options suivantes:

f2py -c -m fib1 fib1.f

ou

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

Ces exemples sont minimes dans le sens où si quelque chose est ignoré dans les lignes de commande f2py ci-dessus, un échec est attendu.

En fait, je parle de cette page: https://numpy.org/devdocs/f2py/usage.html

Là, dans les éléments 2 et 3, nous avons ce qui suit: L'élément 2 consiste à exécuter f2py sans les options -m ou -c , ce qui ne fonctionne apparemment pas. L'article 3 dit

Pour créer un module d'extension, utilisez

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

Si <fortran files> contient un fichier de signature, alors une source pour un module d'extension est construite,
toutes les sources Fortran et C sont compilées, et enfin tous les fichiers objets et bibliothèques sont liés au
module d'extension <modulename>.so qui est sauvegardé dans le répertoire courant.

Si <fortran files> ne contient pas de fichier de signature, alors un module d'extension est construit par
analyse de tous les codes sources Fortran pour les signatures de routine.

D'après ce que vous avez dit, je comprends que nous ne sommes pas censés utiliser directement les sources .c , n'est-ce pas? Si nous générons un fichier .c , est-il inutilisable plus tard?

Merci pour la contribution!

En fait, je parle de cette page: https://numpy.org/devdocs/f2py/usage.html

Cette page décrit les options de ligne f2py commande https://docs.python.org/3.8/extending/index.html

Alors que f2py peut être utilisé pour créer des modules d'extension qui encapsulent également des fonctions C (contenues dans des fichiers .c ) et donc la déclaration "nous ne sommes pas censés utiliser directement les sources .c" est inexacte.

Il faut distinguer les fichiers .c générés par f2py et les fichiers .c qui contiennent des implémentations utilisateur des fonctions C. Le fichier .c généré par f2py n'est utile que lorsque l'on a besoin d'avoir un contrôle total sur la façon dont le module d'extension est construit ou pour le débogage de f2py. Dans tous les autres cas, il n'est pas nécessaire de générer le module d'extension car il sera généré automatiquement dans le processus de construction.

J'ajoute l'explication de

N'hésitez pas à clôturer le problème (ou devrais-je le faire seulement après que le PR ait été accepté?)

Je suggère de fermer lorsque le PR qui aborde cette question est accepté.

Je suggère de fermer lorsque le PR qui aborde cette question est accepté.

+1

@melissawm, vous pouvez également ajouter closes gh-14960 à l'un de vos messages de validation, puis le problème se ferme automatiquement lorsque le PR est fusionné.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

qualiaa picture qualiaa  ·  3Commentaires

Levstyle picture Levstyle  ·  3Commentaires

marcocaccin picture marcocaccin  ·  4Commentaires

Foadsf picture Foadsf  ·  3Commentaires

dcsaba89 picture dcsaba89  ·  3Commentaires