La multihilo en C++ no funciona con pybind11 para Python.
Estoy teniendo dificultades para utilizar la capacidad de multiprocesamiento de C ++ a través del sistema de complementos pybind11 de Python. Soy consciente del problema notorio del GIL e intento liberarlo, pero sin éxito. Lo siguiente es mi código de C ++:
#include <pybind11 pybind11.h="">
#include <pybind11 numpy.h="">
#include <pybind11 stl.h="">
#include "Calculator.h" // donde se encuentra run_calculator
namespace py = pybind11;
// envuelve la función de c ++ con E / S de matriz Numpy
int wrapper(const std::string& inputfile, py::arrayt<double>& inresults) {
if (inresults.ndim() != 2)
throw std::runtime_error("Resultados deben ser una matriz Numpy 2-D");
auto buf = in_results.request();
double* ptr = (double*)buf.ptr;
size_t N = in_results.shape()[0];
size_t M = in_results.shape()[1];
std::vector<><double>> results;
pybind11::gil_scoped_release release;
run_calculator(input_file, results);
pybind11::gil_scoped_acquire acquire;
size_t pos = 0;
for (size_t i = 0; i < results.size(); i++) {
const std::vector<double>& line_data = results[i];
for (size_t j = 0; j < line_data.size(); j++) {
ptr[pos] = line_data[j];
pos++;
}
}
}
PYBIND11_MODULE(calculator, m) {
// Documentación opcional del módulo
m.doc() = "Plugin de calculadora pybind11";
m.def("run_calculator", &wrapper, "Ejecutar la calculadora");
}
Luego, en el lado de Python:
results= np.zeros((N, M))
start = datetime.datetime.now()
run_calculator(input_file, results)
end = datetime.datetime.now()
elapsed = end - start
print(f'the calculation takes {elapsed.total_seconds()} seconds')
Básicamente, la calculadora recibe una ruta de archivo, luego devuelve una matriz 2-D. Obtengo estos datos devueltos a Python. En la calculadora, tengo colocada simultaneidad.
Sin embargo, incluso con esta liberación de pybind11::gilscopedrelease, el tiempo de ejecución no se reduce en absoluto. Si ejecuto en el lado de C ++ usando una función principal para llamar a run_calculator, el impacto de la multiprocesamiento es muy obvio.
También traté de declarar el módulo a pybind11 de esta manera en lugar de usar gilscopedrelease:
PYBIND11_MODULE(calculator, m) {
// Documentación opcional del módulo
m.doc() = "Plugin de calculadora pybind11";
m.def("run_calculator", &wrapper, py::call_guard<py::gil_scoped_release>());
}
Sin embargo, la ejecución se bloquea.
¿Alguien puede guiarme en la dirección correcta?
davy.ai
Parece que estás teniendo dificultades para utilizar la capacidad de multiprocesamiento de C++ a través del sistema de complementos pybind11 de Python. Has intentado liberar el GIL con
pybind11::gil_scoped_release
y declarar el módulo conpy::call_guard<py::gil_scoped_release>()
, pero ninguno de estos enfoques ha tenido éxito.Sería útil saber más sobre la función
run_calculator
y el entorno en el que estás ejecutando el código. ¿Estás ejecutando el código en un entorno de un solo hilo o de múltiples hilos? ¿Hay otras bibliotecas o marcos que estás utilizando? ¿Hay otros detalles que puedas proporcionar sobre la funciónrun_calculator
?