I am using Pybind11 and trying to use OpenMP in it. I call a c++ function from Python using the PyBind interpreter and GIL, then I compute a multithreaded for loop with OpenMP in c++, in which I call within each thread a python function. To do so, I first limit the scope of the GIL with py::gil_scoped_release release; going until the parallel region and then recover it outside the parallel region with `py::gil_scoped_acquire acquire;
The problem is inside the multithreaded for loop. I need to create an interpreter for each thread. My question is: How to do it ?
I have first thought about using the py::scoped_interpreter guard{}, but in the documentation, it said that: 
Creating two concurrent scoped_interpreter guards is a fatal error. So is >calling initialize_interpreter() for a second time after the interpreter has already been initialized.
Do not use the raw CPython API functions Py_Initialize and Py_Finalize as these do not properly handle the lifetime of pybind11’s internal data.
The second point is quite a problem as there is more documentation but only with using the Python C-API, not dealing with Pybind objects 1 2 3
I have looked at the documentation but it doesn't address exactly my problem because it doesn't call Python within multithreading. I have also looked at this 4 but the interpreter is called from c++ and not Python
Any hint would be highly appreciated as I have been blocked for quite some time on this problem. Here is a sample code to illustrate the problem.
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 code
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()))
Compiled with
g++ -O3 -Wall -shared -std=c++14 -fopenmp -fPIC `python3 -m pybind11 --includes` openmp.cpp -o error.so
