Подтвердить что ты не робот

Расширения Python и OpenMP C

У меня есть расширение C, в котором я хотел бы использовать OpenMP. Однако, когда я импортирую свой модуль, я получаю ошибку импорта:


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

Я скомпилировал модуль с -fopenmp и -lgomp. Это потому, что моя установка Python не была скомпилирована с флагом -fopenmp? Должен ли я построить Python из источника? Или есть какая-то другая возможность? Это единственный раз, когда я фактически использую openmp в своем модуле:


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

Я хотел бы придерживаться openmp, если это возможно, только потому, что это так просто, и распараллеливание в этом случае подходит ему.

РЕДАКТИРОВАТЬ: Я забил пулю и перекомпилировал Python с поддержкой OpenMP. Теперь мой модуль работает отлично, но это не очень хорошее решение. Я не могу это распространять, если требуется полная перекомпиляция Python. Так кто-нибудь знает об этом? Может ли ctypes работать, возможно?

РЕШИТЬ! Это была простая проблема связи. (Я перестроил Python для этого?!) OpenMP не был должным образом связан во время компиляции модуля. Таким образом, возможно загрузить расширение C Python, использующее OpenMP.

4b9b3361

Ответ 1

Чтобы сделать его более понятным, вот что ваш setup.py должен выглядеть так:

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


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

Ответ 2

Я знаю, что это датированный пост, но я расскажу о своем опыте, поскольку я тоже столкнулся с этой же проблемой, но при использовании f2py в командной строке. Я изначально компилировал свою подпрограмму Fortran 90 с поддержкой OpenMP, используя

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

который успешно создал общий объект sub.so. Однако попытка импортировать это из оболочки Python вызвала аналогичный символ undefined ImportError. Тем не менее, как заявил оригинальный автор, потому что я пытался передать и -fopenmp и -lgomp компилятору, тогда как только ему нужно передать -fopenmp, а -lgomp следует передать компоновщику.

Поэтому я должен был делать следующее

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

И что это, проблема решена, теперь я могу импортировать свою подпрограмму.

Ответ 3

Это была простая проблема связывания. OpenMP не был правильно связан во время компиляции модуля. Таким образом, можно загрузить расширение C Python, которое использует OpenMP. -fopenmp должен быть передан компилятору и -lgomp к компоновщику - если вы используете distutils, убедитесь, что setup.py настроен правильно. Rebuilding Python также работал, я предполагаю, потому что я правильно связал OpenMP с Python, поэтому, когда Python загрузил модуль, библиотека уже была правильно связана с.