Câu hỏi Phần mở rộng Python và OpenMP C


Tôi có một 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, tôi nhận được lỗi nhập:


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

Tôi đã biên dịch các mô-đun với -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 module 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 nó có thể, chỉ vì nó rất dễ dàng và song song trong trường hợp này phù hợp với nó tốt.

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 THÍCH! Đó 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. Do đó, nó  có thể tải phần mở rộng C Python sử dụng OpenMP.


27
2017-08-26 06:36


gốc


Bạn có thể cân nhắc việc 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ễ nhìn hơn (và có thể được upvoted). - Michael Ratanapintha
Cảm ơn, tôi sẽ làm điều đó. - ajduff574


Các câu trả lời:


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

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


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

16
2017-10-08 19:25



Bây giờ, làm thế nào để làm điều đó trong một nền tảng cách mà làm việc với các phiên bản của gcc, msvc và Clang có hỗ trợ openmp và fallback gracefully nếu không? - Colonel Panic
@ColonelPanic: Tôi cũng rất muốn biết điều đó. - luispedro


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 mình khi tôi cũng gặp phải vấn đề tương tự, nhưng khi sử dụng f2py tại dòng lệnh. Ban đầu tôi biên soạn OpenMP của tôi cho phép chương trình con Fortran 90 sử dụng

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

đã tạo thành công đối tượng được 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 truyền cả hai -fopenmp và -lgomp đến trình biên dịch, trong khi chỉ -fopenmp nên được truyền cho nó, và -lgomp nên được truyền cho trình liên kết.

Do đó, tôi nên 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, bây giờ tôi có thể nhập chương trình con của tôi.


6
2017-12-06 02:33





Đó 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 tới 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 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.


3
2017-08-30 03:00