2010-08-26 34 views
27

Tengo una extensión C en la que me gustaría usar OpenMP. Cuando importo mi módulo, sin embargo, me sale un error de importación:Extensiones Python y OpenMP C


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

He compilado el módulo con -fopenmp y -lgomp. ¿Esto es porque mi instalación de Python no se compiló con el indicador -fopenmp? ¿Tendré que construir Python desde la fuente? ¿O hay alguna otra posibilidad? Esta es la única vez que realmente utilizo en mi OpenMP módulo:


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

me gustaría seguir con OpenMP si es posible, simplemente porque es muy fácil y la paralelización en este caso se adapte bien.

EDITAR: Pordé la viñeta y recompuse Python con soporte OpenMP. Mi módulo funciona perfectamente ahora, pero esta no es realmente una gran solución. Realmente no puedo distribuir esto si requiere una compilación completa de Python. Entonces, ¿alguien sabe alguna forma de evitar esto? ¿Podrían funcionar los ctypes?

¡RESUELTO! Fue un simple tema de enlace. (¿Reconstruí Python para eso ?!) OpenMP no se vinculó correctamente durante la compilación del módulo. Por lo tanto, IS es posible cargar una extensión C Python que use OpenMP.

+0

Puede considerar copiar su solución en una respuesta "real" publicada bajo esta pregunta, para que sea más fácil de ver (y se puede subir). –

+0

Gracias, lo haré. – ajduff574

Respuesta

16

Sólo para que quede más claro, aquí es lo que su setup.py debe verse como:

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


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

Ahora, ¿cómo hacerlo de una manera multiplataforma que funciona con versiones de gcc, msvc y Clang que admiten openmp y repliegue con gracia de lo contrario? –

+0

@ColonelPanic: También me gustaría saberlo. – luispedro

3

Era un problema de enlace simple. OpenMP no se ha vinculado correctamente durante la compilación del módulo. Por lo tanto, es posible cargar una extensión C Python que use OpenMP. -fopenmp tiene que pasarse al compilador y -lgomp al enlazador. Si estás utilizando distutils, asegúrate de que setup.py esté configurado correctamente. La reconstrucción de Python también funcionó, supongo, porque había vinculado correctamente OpenMP con Python, por lo que cuando Python cargó el módulo, la biblioteca ya estaba correctamente vinculada.

6

Sé que esto es un post fechado, pero voy a compartir mi experiencia como yo también encontré con este exacta mismo problema, pero al usar f2py en la línea de comando. Estaba recopilando originalmente mi OpenMP habilitado Fortran 90 subrutina usando

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

el que creó con éxito el objeto compartido sub.so. Sin embargo, al tratar de importar esto desde un shell de Python, se produjo el símbolo undefined similar ImportError. Sin embargo, como el autor original declaró que se debe a que estaba intentando pasar tanto -fopenmp como -lgomp al compilador , mientras que solo se le debe pasar -fopenmp, y -lgomp se debe pasar al vinculador.

Por lo tanto, debería haber estado haciendo lo siguiente

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

Y eso es todo, problema resuelto, ahora puedo importar mi subrutina.

Cuestiones relacionadas