我编写了一个 Python 脚本,该脚本调用使用 OpenMP 并行化的 C 函数(从 Python 到 C 函数的变量是使用 ctypes-wrapper 传递的)。 C 函数正常工作,产生所需的输出。但我在 Python 代码末尾遇到了段错误。我怀疑这与 OpenMP 生成的线程有关,因为禁用 OpenMP 时不会发生段错误。
在代码的 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-----
}
我有以下问题和相关的困惑:
Python 对 C 函数内 OpenMP 生成的线程的操作有任何控制吗?我问这个问题的原因是 C 函数接收指向 Python 在堆中分配的数组的指针。 OpenMP 线程是否可以并行地对该数组执行操作,而无需关心它的分配位置?
在调用 C 函数之前,我是否需要在 Python 代码中执行任何操作,例如释放 GIL 以允许在 C 函数中生成 OpenMP 线程?如果是,如何做到这一点?
我是否必须在 C 函数中释放 GIL(在 OpenMP 并行 block 之前)?
最佳答案
我有 SWIG ( http://swig.org ),它是一个用于 Python 和其他语言的 C 和 C++ 包装器生成器,为我组织 GIL 版本。生成的代码看起来并不简单,并且正在使用 PEP311 中的新释放/获取技术。 。但是,PEP 中解释的旧技术可能足以满足您的需要。我希望稍后有更有能力的人回答,但我想这个答案总比没有好。但是 OpenMP 循环中的错误没有得到妥善处理,您是否在 Python 之外使用 OpenMP 检查了 C 函数?
关于python - 从 Python 中使用 OpenMP 调用 C 函数会导致最后出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43775377/