diff --git a/python_bindings/src/PyError.cpp b/python_bindings/src/PyError.cpp index bfc7459424f3..8ff0f4f53aca 100644 --- a/python_bindings/src/PyError.cpp +++ b/python_bindings/src/PyError.cpp @@ -10,6 +10,7 @@ void halide_python_error(JITUserContext *, const char *msg) { } void halide_python_print(JITUserContext *, const char *msg) { + py::gil_scoped_acquire acquire; py::print(msg, py::arg("end") = ""); } diff --git a/python_bindings/src/PyFunc.cpp b/python_bindings/src/PyFunc.cpp index 7ead1e9b9d6f..f87666c16f82 100644 --- a/python_bindings/src/PyFunc.cpp +++ b/python_bindings/src/PyFunc.cpp @@ -117,6 +117,7 @@ void define_func(py::module &m) { .def( "realize", [](Func &f, Buffer<> buffer, const Target &target) -> void { + py::gil_scoped_release release; f.realize(buffer, target); }, py::arg("dst"), py::arg("target") = Target()) @@ -125,6 +126,7 @@ void define_func(py::module &m) { .def( "realize", [](Func &f, std::vector> buffers, const Target &t) -> void { + py::gil_scoped_release release; f.realize(Realization(buffers), t); }, py::arg("dst"), py::arg("target") = Target()) @@ -132,7 +134,12 @@ void define_func(py::module &m) { .def( "realize", [](Func &f, const std::vector &sizes, const Target &target) -> py::object { - return realization_to_object(f.realize(sizes, target)); + std::optional r; + { + py::gil_scoped_release release; + r = std::move(f.realize(sizes, target)); + } + return realization_to_object(*r); }, py::arg("sizes") = std::vector{}, py::arg("target") = Target()) diff --git a/python_bindings/src/PyPipeline.cpp b/python_bindings/src/PyPipeline.cpp index ae5257492138..155b74821f72 100644 --- a/python_bindings/src/PyPipeline.cpp +++ b/python_bindings/src/PyPipeline.cpp @@ -96,6 +96,7 @@ void define_pipeline(py::module &m) { .def( "realize", [](Pipeline &p, Buffer<> buffer, const Target &target) -> void { + py::gil_scoped_release release; p.realize(Realization(buffer), target); }, py::arg("dst"), py::arg("target") = Target()) @@ -103,13 +104,19 @@ void define_pipeline(py::module &m) { // This will actually allow a list-of-buffers as well as a tuple-of-buffers, but that's OK. .def( "realize", [](Pipeline &p, std::vector> buffers, const Target &t) -> void { + py::gil_scoped_release release; p.realize(Realization(buffers), t); }, py::arg("dst"), py::arg("target") = Target()) .def( "realize", [](Pipeline &p, std::vector sizes, const Target &target) -> py::object { - return realization_to_object(p.realize(std::move(sizes), target)); + std::optional r; + { + py::gil_scoped_release release; + r = std::move(p.realize(std::move(sizes), target)); + } + return realization_to_object(*r); }, py::arg("sizes") = std::vector{}, py::arg("target") = Target()) diff --git a/src/PythonExtensionGen.cpp b/src/PythonExtensionGen.cpp index 3a6ce49bb7b8..bcfa189acf63 100644 --- a/src/PythonExtensionGen.cpp +++ b/src/PythonExtensionGen.cpp @@ -347,7 +347,9 @@ void PythonExtensionGen::compile(const LoweredFunc &f) { // Python already converted this. } } - dest << " int result = " << f.name << "("; + dest << " int result;\n"; + dest << " Py_BEGIN_ALLOW_THREADS\n"; + dest << " result = " << f.name << "("; for (size_t i = 0; i < args.size(); i++) { if (i > 0) { dest << ", "; @@ -359,6 +361,7 @@ void PythonExtensionGen::compile(const LoweredFunc &f) { } } dest << ");\n"; + dest << " Py_END_ALLOW_THREADS\n"; release_buffers(); dest << R"INLINE_CODE( if (result != 0) {