2010-08-26 8 views
27

Ich habe eine C-Erweiterung, in der ich OpenMP verwenden möchte. Wenn ich mein Modul importieren, obwohl, erhalte ich einen Importfehler:Python und OpenMP C Extensions


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

ich das Modul mit -fopenmp und -lgomp kompiliert haben. Liegt das daran, dass meine Python-Installation nicht mit dem Flag -fopenmp kompiliert wurde? Muss ich Python aus der Quelle erstellen? Oder gibt es eine andere Möglichkeit? Dies ist das einzige Mal, dass ich tatsächlich openmp in meinem Modul verwenden:


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

Ich mag mit openmp bleiben, wenn es möglich ist, nur weil es so einfach ist und die Parallelisierung in diesem Fall paßt es gut.

EDIT: Ich biss das Bullet und rekompilierte Python mit OpenMP-Unterstützung. Mein Modul funktioniert jetzt perfekt, aber das ist keine wirklich gute Lösung. Ich kann das nicht wirklich verteilen, wenn es eine komplette Neukompilierung von Python erfordert. Kennt also irgendjemand etwas in der Umgebung? Würden Cytypen vielleicht funktionieren?

Gelöst! Es war ein einfaches Verknüpfungsproblem. (Ich habe Python dafür neu erstellt ?!) OpenMP wurde während der Kompilierung des Moduls nicht richtig verbunden. So ist es IS möglich, eine C Python-Erweiterung zu laden, die OpenMP verwendet.

+0

Sie könnten in Erwägung ziehen, Ihre Lösung in eine "echte" Antwort zu kopieren, die unter dieser Frage angezeigt wird, so dass sie einfacher zu sehen ist (und hochgestuft werden kann). –

+0

Danke, ich werde das tun. – ajduff574

Antwort

16

Gerade deutlicher, hier zu machen ist, was Ihr setup.py aussehen sollte:

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


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

Nun, wie man das auf eine plattformübergreifende Weise, die mit Versionen von gcc, msvc und Clang funktioniert, die Openmp und Fallback ansonsten würdevoll unterstützt? –

+0

@ColonelPanic: Das würde ich auch gerne wissen. – luispedro

3

Es war ein einfaches Verknüpfungsproblem. OpenMP wurde während der Kompilierung des Moduls nicht ordnungsgemäß verknüpft. Es ist also möglich, eine C Python-Erweiterung zu laden, die OpenMP verwendet. -fopenmp muss an den Compiler und -lgomp an den Linker übergeben werden. Wenn Sie distutils verwenden, stellen Sie sicher, dass setup.py ordnungsgemäß konfiguriert ist. Der Neuaufbau von Python funktionierte auch, denke ich, weil ich OpenMP mit Python richtig verbunden hatte, also wenn Python das Modul geladen hat, war die Bibliothek bereits richtig verlinkt.

6

Ich weiß, dass dies eine datierte Post ist, aber ich werde meine Erfahrung teilen, wie ich auch in diesen lief genau Gleiches Problem, aber bei Verwendung von f2py an der Befehlszeile. Ich war Kompilieren ursprünglich meine OpenMP Fortran 90 Unterroutine

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

, die erfolgreich erstellt das gemeinsame Objekt sub.so mit aktiviert. Bei dem Versuch, dies aus einer Python-Shell zu importieren, wurde jedoch das undefined Symbol ImportError erzeugt. Wie der ursprüngliche Autor feststellte, liegt das daran, dass ich versuchte, sowohl -fopenmp als auch -lgomp an den Compiler zu übergeben, während nur -fopenmp an ihn übergeben werden sollte und -lgomp an den Linker übergeben werden sollte.

Deshalb soll ich tut die folgenden

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

wurde, und das ist es, Problem gelöst, ich jetzt mein Unterprogramm importieren.