2010-08-26 36 views
27

Tôi có phần mở rộng C trong đó tôi muốn sử dụng OpenMP. Tuy nhiên, khi tôi nhập mô-đun của mình, tôi gặp lỗi nhập:Tiện ích mở rộng của Python và OpenMP C


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

Tôi đã biên dịch mô-đun bằng -fopenmp và -lgomp. Đây có phải là vì cài đặt Python của tôi không được biên dịch với cờ -fopenmp? Tôi có phải xây dựng Python từ nguồn không? Hay liệu có khả năng nào khác không? Đây là lần duy nhất tôi thực sự sử dụng openmp trong mô-đun của mình:


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

Tôi muốn gắn bó với openmp nếu có thể, chỉ vì nó dễ dàng và song song trong trường hợp này phù hợp với nó.

EDIT: Tôi bit viên đạn và biên dịch lại Python với hỗ trợ OpenMP. Mô-đun của tôi hoạt động hoàn hảo ngay bây giờ, nhưng đây không phải là giải pháp tuyệt vời. Tôi thực sự không thể phân phối nó nếu nó đòi hỏi một biên dịch lại đầy đủ của Python. Vì vậy, không ai biết một số cách xung quanh này? Liệu ctypes có hoạt động được không?

GIẢI PHÁP! Đó là một vấn đề liên kết đơn giản. (Tôi xây dựng lại Python cho rằng ?!) OpenMP đã không được liên kết đúng trong quá trình biên dịch của các mô-đun. Vì vậy, IS có thể tải phần mở rộng C Python sử dụng OpenMP.

+0

Bạn có thể xem xét sao chép giải pháp của mình thành câu trả lời "thực" được đăng trong câu hỏi này, để dễ xem hơn (và có thể được upvoted). –

+0

Cảm ơn, tôi sẽ làm điều đó. – ajduff574

Trả lời

16

Chỉ cần để làm cho nó rõ ràng hơn, đây là những gì setup.py của bạn sẽ giống như thế:

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


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

Bây giờ, làm thế nào để làm điều đó theo cách đa nền tảng hoạt động với các phiên bản gcc, msvc và Clang có hỗ trợ openmp và fallback một cách duyên dáng nếu không? –

+0

@ColonelPanic: Tôi cũng rất muốn biết điều đó. – luispedro

3

Đó là một vấn đề liên kết đơn giản. OpenMP không được liên kết đúng cách trong quá trình biên dịch module. Vì vậy, nó có thể tải một phần mở rộng C Python sử dụng OpenMP. -fopenmp phải được chuyển đến trình biên dịch và -lgomp cho trình liên kết - nếu bạn đang sử dụng các distutils, hãy chắc chắn rằng setup.py của bạn được cấu hình đúng cách. Xây dựng lại Python cũng làm việc, tôi đoán, bởi vì tôi đã liên kết đúng cách OpenMP với Python, vì vậy khi Python nạp mô-đun thư viện đã được liên kết đúng cách.

6

Tôi biết đây là một bài đăng ngày, nhưng tôi sẽ chia sẻ kinh nghiệm của tôi khi tôi quá chạy vào này chính xác cùng một vấn đề, nhưng khi sử dụng f2py tại dòng lệnh. Tôi ban đầu được biên soạn OpenMP tôi kích hoạt Fortran 90 chương trình con sử dụng

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

mà tạo thành công các đối tượng chia sẻ sub.so. Tuy nhiên, cố gắng để nhập này từ một vỏ Python sản xuất tương tự biểu tượng không xác định ImportError. Tuy nhiên, như tác giả ban đầu đã nói rằng đó là vì tôi đã cố gắng chuyển cả hai -fopenmp và -lgomp tới trình biên dịch , trong khi chỉ -fopenmp nên được truyền cho nó, và -lgomp nên được chuyển cho trình liên kết.

Vì vậy, tôi cần phải có được cách làm như sau

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

Và đó là nó, vấn đề được giải quyết, tôi bây giờ có thể nhập khẩu chương trình con của tôi.

Các vấn đề liên quan