2010-08-26 6 views
27

J'ai une extension C dans laquelle j'aimerais utiliser OpenMP. Quand j'importer mon module, cependant, je reçois une erreur d'importation:Extensions Python et OpenMP C


ImportError: /home/.../_entropysplit.so: undefined symbol: GOMP_parallel_end 

J'ai compilé le module avec -fopenmp et -lgomp. Est-ce parce que mon installation Python n'a pas été compilée avec le drapeau -fopenmp? Devrai-je construire Python à partir de la source? Ou y a-t-il une autre possibilité? C'est la seule fois que je l'utilise en fait OpenMP dans mon module:


unsigned int feature_index; 
#pragma omp parallel for 
for (feature_index = 0; feature_index < num_features; feature_index++) { 

J'aimerais rester avec OpenMP s'il est possible, juste parce qu'il est si facile et la parallélisation dans ce cas convient bien.

EDIT: J'ai mordu la puce et recompilé Python avec le support OpenMP. Mon module fonctionne parfaitement maintenant, mais ce n'est pas vraiment une bonne solution. Je ne peux pas vraiment le distribuer s'il nécessite une recompilation complète de Python. Est-ce que quelqu'un sait quelque chose à ce sujet? Est-ce que les ctypes fonctionneraient peut-être?

RÉSOLU! C'était un problème de liaison simple. (J'ai reconstruit Python pour cela?!) OpenMP n'était pas correctement lié pendant la compilation du module. Il est donc possible de charger une extension C Python utilisant OpenMP.

+0

Vous pourriez envisager de copier votre solution dans une «vraie» réponse publiée sous cette question, afin qu'elle soit plus facile à voir (et qu'elle puisse être mise à jour). –

+0

Merci, je vais le faire. – ajduff574

Répondre

16

Juste pour le rendre plus clair, voici ce que votre setup.py devrait ressembler à:

ext = Extension(
     'milk.unsupervised._som', 
     sources = ['milk/unsupervised/_som.cpp'], 
     extra_compile_args=['-fopenmp'], 
     extra_link_args=['-lgomp']) 


... 
setup(..., ext_modules = [ext]) 
+1

Maintenant, comment faire cela d'une manière multiplate-forme qui fonctionne avec les versions de gcc, msvc et Clang qui supportent OpenMP et fallback gracieusement sinon? –

+0

@ColonelPanic: J'aimerais aussi savoir ça. – luispedro

3

C'était un problème de liaison simple. OpenMP n'était pas correctement lié lors de la compilation du module. Il est donc possible de charger une extension C Python qui utilise OpenMP. -fopenmp doit être passé au compilateur et -lgomp à l'éditeur de liens - si vous utilisez distutils, assurez-vous que votre setup.py est correctement configuré. La reconstruction de Python a aussi fonctionné, je suppose, parce que j'avais correctement lié OpenMP avec Python, donc quand Python a chargé le module, la bibliothèque était déjà correctement liée.

6

Je sais que c'est un post daté, mais je vais partager mon expérience que moi aussi je suis tombé sur cette exacte même problème, mais lors de l'utilisation de f2py sur la ligne de commande. Je compilait mon origine OpenMP activé sous-routine Fortran 90 en utilisant

f2py --fcompiler=gfortran --f90flags='-fopenmp -lgomp' -m sub -c sub.90 

qui a créé avec succès l'objet partagé sub.so. Cependant, en essayant d'importer ceci à partir d'un shell Python produit le symbole non défini similaire ImportError. Cependant, comme l'auteur original l'a déclaré, c'est parce que j'essayais de passer à la fois -fopenmp et -lgomp au compilateur , alors que seulement -fopenmp devrait lui être passé, et -lgomp devrait être passé à l'éditeur de liens.

Par conséquent, je suis en train de faire ce qui suit

f2py --fcompiler=gfortran --f90flags='-fopenmp' -lgomp -m sub -c sub.f90 

Et voilà, le problème est résolu, je peux maintenant importer mon sous-programme.