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

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

28 голосов
/ 26 августа 2010

У меня есть расширение 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 не был должным образом связан во время компиляции модуля. Так что IS можно загрузить расширение C Python, использующее OpenMP.

Ответы [ 3 ]

16 голосов
/ 08 октября 2010

Просто чтобы прояснить ситуацию, вот как должен выглядеть ваш setup.py:

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


...
setup(..., ext_modules = [ext])
7 голосов
/ 06 декабря 2013

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

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

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

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

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

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

3 голосов
/ 30 августа 2010

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

...