当我将Pybind11与OpenMP一起使用时,它的功能特性有问题。我做了一些研究,我的问题听起来与2年前这请求中的问题相当相似,但尽管这个公关已经结束,而且问题似乎是固定的,但我仍然有这个问题。我创建的代码示例有望更好地解释我的问题:
b.h
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include <omp.h>
namespace py = pybind11;
class B {
public:
B(int n, const int& initial_value);
void map(const std::function<int(int)> &f);
private:
int n;
int* elements;
};b.cpp
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include "b.h"
namespace py = pybind11;
B::B(int n, const int& v)
: n(n) {
elements = new int[n];
#pragma omp parallel for
for (int i = 0; i < n; i++) {
elements[i] = v;
}
}
void B::map(const std::function<int(int)> &f) {
#pragma omp parallel for
for (int i = 0; i < n; i++) {
elements[i] = f(elements[i]);
}
}
PYBIND11_MODULE(m, handle) {
handle.doc() = "Example Module";
py::class_<B>(handle, "B")
.def(py::init<int, int>())
.def("map", &B::map)
;
}CMakeLists.txt
cmake_minimum_required(VERSION 3.4...3.18)
project(example)
find_package(OpenMP)
add_subdirectory(pybind11)
pybind11_add_module(m b.cpp)
if(OpenMP_CXX_FOUND)
target_link_libraries(m PUBLIC OpenMP::OpenMP_CXX)
else()
message( FATAL_ERROR "Your compiler does not support OpenMP" )
endif()test.py
from build.m import *
def test(i):
return i * 20
b = B(2, 2)
b.map(test)基本上,我有一个数组,其中我希望使用for-循环将Python函数应用于每个元素。我知道这是functional和OpenMP的一个问题,特别是因为在我的项目的其他部分,我成功地使用了OpenMP,而且如果我不使用OpenMP,Functional也在工作。
编辑:它冻结在地图功能,并必须终止。我正在使用Ubuntu21.10、Python3.9、GCC 11.2.0、OpenMP 4.5和pybind11回购的最新版本。
发布于 2022-01-11 14:42:47
您可能会遇到OpenMP的调度程序和Python的GIL (全局解释器锁)之间的死锁。
我建议将gdb附加到您的进程中,并查看线程在哪里验证这才是真正的问题。
IMHO将Python函数和OpenMP这样的函数混合在一起是自找麻烦。如果您想要多线程的Python函数,您可以使用multiprocessing.pool.ThreadPool。但是,除非您的函数在大多数情况下释放GIL,否则您将无法从多线程中获益。
https://stackoverflow.com/questions/70652383
复制相似问题