2010-08-26 189 views
27

我有一個C擴展,我想使用OpenMP。當我輸入我的模塊,但是,我得到一個導入錯誤:Python和OpenMP C擴展


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,如果有可能,只是因爲它是如此簡單,在這種情況下,並行適合很好。

編輯:我咬緊牙關,用OpenMP支持重新編譯Python。我的模塊現在完美工作,但這不是一個很好的解決方案。如果需要Python的完整重新編譯,我無法真正分配它。那麼是否有人知道一些解決辦法? ctypes可以工作嗎?

已解決!這是一個簡單的鏈接問題。 (我爲此重建了Python!)在編譯模塊期間,OpenMP沒有正確連接。因此可以加載使用OpenMP的C Python擴展。

+0

您可能會考慮將您的解決方案複製到根據此問題發佈的「真實」答案中,以便更容易看到(並且可以提高)。 – 2010-08-30 02:18:54

+0

謝謝,我會這樣做的。 – ajduff574 2010-08-30 02:55:35

回答

16

只是爲了更清楚,這裏是你的setup.py應該是什麼樣子:

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


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

現在,如何以跨平臺的方式來處理gcc,msvc和Clang的版本,否則它們會優雅地支持openmp和fallback? – 2015-11-29 20:14:41

+0

@ColonelPanic:我也很想知道。 – luispedro 2015-12-03 17:46:27

3

這是一個簡單的鏈接問題。在編譯模塊期間,OpenMP沒有正確連接。所以可以加載使用OpenMP的C Python擴展。 -fopenmp必須傳遞給編譯器,-lgomp傳遞給鏈接器 - 如果你使用distutils,確保你的setup.py配置正確。我猜測,重建Python也很有效,因爲我已經將OpenMP與Python正確關聯,所以當Python加載模塊時,庫已經正確鏈接到了。

6

我知道這是一個過時的帖子,但我會分享我的經驗,我也遇到了這個確切同樣的問題,但在命令行使用f2py。我本來編譯我的OpenMP啓用使用

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

Fortran 90的子程序,其成功地創建了共享對象sub.so。但是,試圖從Python外殼導入此類產生類似的未定義符號 ImportError。但是,原作者聲明這是因爲我試圖將-fopenmp和-lgomp傳遞給編譯器,而只傳遞-fopenmp給它,並且-lgomp應該傳遞給鏈接器。

所以,我一直在做以下

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

就是這樣,問題就解決了,現在我可以導入我的子程序。