Я использую Pybind11 и пытаюсь использовать в нем OpenMP. Я вызываю функцию c ++ из Python, используя интерпретатор PyBind и GIL, затем вычисляю многопоточность для l oop с OpenMP в c ++, в котором в каждом потоке я вызываю python функцию. Для этого я сначала ограничиваю область действия GIL py::gil_scoped_release release;
до параллельной области, а затем восстанавливаю ее вне параллельной области с помощью `py :: gil_scoped_acquire acqu;
Проблема заключается в многопоточности для л oop. Мне нужно создать интерпретатор для каждого потока. У меня вопрос: как это сделать?
Сначала я подумал об использовании py::scoped_interpreter guard{}
, но в документации сказано, что:
Создание двух одновременных охранников scoped_interpreter является фатальной ошибкой. Так что> вызывается initialize_interpreter () во второй раз после того, как интерпретатор уже был инициализирован.
Не используйте сырые CPython API-функции Py_Initialize и Py_Finalize, поскольку они неправильно обрабатывают время жизни Внутренние данные pybind11.
Второй момент довольно проблематичен, так как имеется больше документации, но только с использованием Python C -API, не имеющим дело с объектами Pybind 1 2 3
Я посмотрел документацию , но она не решает точно мою проблему, потому что она не вызывает Python в многопоточности. Я также посмотрел на это 4 , но интерпретатор вызывается из c ++, а не Python
Любая подсказка будет высоко оценена, так как я уже довольно давно заблокирован по этой проблеме. Вот пример кода для иллюстрации проблемы.
py::object create_seq(
py::object self
){
std::vector<py::object> dict = self.cast<std::vector<py::object>>();
py::gil_scoped_release release;
#pragma omp parallel for ordered schedule(dynamic)
for(unsigned int i=0; i<dict.size(); i++) {
?? WHAT HAPPENS HERE ??
std::cout << i << std::endl;
#pragma omp ordered
dict[i].attr("attribute") = open.attr("parallel")().cast<int>();
}
py::gil_scoped_acquire acquire;
return self;
}
PYBIND11_MODULE(error, m){
m.doc() = "pybind11 module for iterating over generations";
m.def("create_seq", &create_seq,
"the function which creates a sequence");
}
Python код
import error
class test():
def __init__(self):
self.attribute = None
def func():
return 2
if __name__ == '__main__':
dict = {}
for i in range(50):
dict[i] = test()
pop = error.create_seq(list(dict.values()))
Составлено с
g++ -O3 -Wall -shared -std=c++14 -fopenmp -fPIC `python3 -m pybind11 --includes` openmp.cpp -o error.so