2017-05-04 125 views
-1

我已經編寫了一個調用C函數的Python腳本,該腳本使用OpenMP並行化(使用ctypes-wrapper傳遞從Python到C函數的變量)。 C函數可以正確地生成所需的輸出。但是,我在Python代碼的最後得到了一個分段錯誤。我懷疑它與OpenMP產生的線程有關,因爲當OpenMP被禁用時seg-fault不會發生。從Python中調用OpenMP的C函數導致段尾出現段錯誤

在代碼的Python端(它調用外部C-功能)我有:

... 
C_Func = ctypes.cdll.LoadLibrary ('./Cinterface.so') 

C_Func.Receive_Parameters.argtypes = (...list of ctypes variable-type ...) 
C_Func.Receive_Parameters.restype = ctypes.c_void_p 

C_Func.Perform_Calculation.argtypes = () 
C_Func.Perform_Calculation.restypes = ctypes.c_void_p 

和在C端,該函數的一般形式是:

void Receive_Parameters (....list of c variable-type ...) 
{ 
    ---Take all data and parameters coming from python--- 
    return; 
} 

void Perform_Calculation () 
{ 

#pragma omp parallel default(shared) num_threads(8) private (....) 
{ 
    #pragma omp for schedule (static, 1) reduction (+:p) 
    p+= core_calculation (...list of variables....) 
} 
    return; 
} 


float core_calculation (...list of variables...) 
{ 
    ----all calculations done here----- 
} 

我有以下問題和相關的困惑:

  1. Python是否有任何控制線程的操作由C函數內部的OpenMP產生?我問這個問題的原因是C函數接收指向由Python在堆中分配的數組的指針。 OpenMP線程可以並行執行對此陣列的操作,而不會打擾它分配的位置?

  2. 在調用C函數之前,我是否需要在Python代碼中做任何事情,例如釋放GIL以允許在C函數中產生OpenMP線程?如果是的話,那麼怎麼做呢?

  3. 我是否必須在C函數中釋放GIL(在OpenMP並行塊之前)?

+0

忘了補充,C函數接受指向python中分配的數組的指針。只是想知道這是否可能是seg-fault的原因之一。 – Rak

+0

你忘了添加[mcve](仔細閱讀該頁面)。推測你的錯誤沒有特定的代碼來重現它是沒有用的。 – Zulan

+0

對不起,代碼太長,無法在此發佈。我已經提出了一些疑問,我認爲這可能是我看到的seg故障的原因。 – Rak

回答

-1

我痛飲(http://swig.org),一個C和C++爲Python等語言組織GIL釋放我的包裝發生器。生成的代碼看起來並不重要,並且正在使用來自PEP311的新發布/獲取技術。但是,在PEP中解釋的舊技術對您來說可能就足夠了。我希望稍後有更多能幹的人會回答,但我猜這個答案勝於無。但是,OpenMP循環中的錯誤並沒有得到妥善處理,您是否使用Python以外的OpenMP檢查了C函數?

+0

是的,OpenMP的C函數在Python之外很好運行。 – Rak