Skip to content

Commit 7c176c2

Browse files
committed
Python: Release GIL during Processor::process()
1 parent dc6a2eb commit 7c176c2

File tree

5 files changed

+42
-3
lines changed

5 files changed

+42
-3
lines changed

python/src/pybindings/feature_bindings.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,59 +42,70 @@ class PyFeatureBase : public Feature
4242

4343
double get_double(const std::string& name) const override
4444
{
45+
py::gil_scoped_acquire gil;
4546
return get_py(name).cast<double>();
4647
}
4748

4849
DoubleArray get_double_array(const std::string& name) const override
4950
{
51+
py::gil_scoped_acquire gil;
5052
py::array_t<double> arr = get_py(name);
5153
return { arr.data(), static_cast<std::size_t>(arr.size()) };
5254
}
5355

5456
std::int32_t get_int(const std::string& name) const override
5557
{
58+
py::gil_scoped_acquire gil;
5659
return get_py(name).cast<int32_t>();
5760
}
5861

5962
std::int64_t get_int64(const std::string& name) const override
6063
{
64+
py::gil_scoped_acquire gil;
6165
return get_py(name).cast<int64_t>();
6266
}
6367

6468
IntegerArray get_integer_array(const std::string& name) const override
6569
{
70+
py::gil_scoped_acquire gil;
6671
py::array_t<std::int32_t> arr = get_py(name);
6772
return { arr.data(), static_cast<std::size_t>(arr.size()) };
6873
}
6974

7075
Integer64Array get_integer64_array(const std::string& name) const override
7176
{
77+
py::gil_scoped_acquire gil;
7278
py::array_t<std::int64_t> arr = get_py(name);
7379
return { arr.data(), static_cast<std::size_t>(arr.size()) };
7480
}
7581

7682
std::string get_string(const std::string& name) const override
7783
{
84+
py::gil_scoped_acquire gil;
7885
return get_py(name).cast<std::string>();
7986
}
8087

8188
void set(const std::string& name, std::string value) override
8289
{
90+
py::gil_scoped_acquire gil;
8391
set_py(name, py::str(value));
8492
}
8593

8694
void set(const std::string& name, std::int32_t value) override
8795
{
96+
py::gil_scoped_acquire gil;
8897
set_py(name, py::int_(value));
8998
}
9099

91100
void set(const std::string& name, std::int64_t value) override
92101
{
102+
py::gil_scoped_acquire gil;
93103
set_py(name, py::int_(value));
94104
}
95105

96106
void set(const std::string& name, double value) override
97107
{
108+
py::gil_scoped_acquire gil;
98109
set_py(name, py::float_(value));
99110
}
100111

@@ -116,6 +127,8 @@ class PyFeatureBase : public Feature
116127
template<typename T>
117128
void set_array(const std::string& name, const T& value)
118129
{
130+
py::gil_scoped_acquire gil;
131+
119132
std::size_t shape[1]{ value.size };
120133
py::array_t<typename T::value_type> values(shape);
121134
auto x = values.template mutable_unchecked<1>();
@@ -127,6 +140,7 @@ class PyFeatureBase : public Feature
127140

128141
ValueType field_type(const std::string& name) const override
129142
{
143+
py::gil_scoped_acquire gil;
130144
py::object value = get_py(name);
131145

132146
try {
@@ -139,6 +153,8 @@ class PyFeatureBase : public Feature
139153
const GEOSGeometry* geometry() const override
140154
{
141155
if (m_geom == nullptr) {
156+
py::gil_scoped_acquire gil;
157+
142158
py::object geom = geometry_py();
143159
if (py::isinstance<py::bytes>(geom)) {
144160
py::buffer_info info = py::buffer(geom).request();
@@ -171,6 +187,8 @@ class PyFeatureBase : public Feature
171187
m_geom = nullptr;
172188
}
173189

190+
py::gil_scoped_acquire gil;
191+
174192
if (other == nullptr) {
175193
set_geometry_py(py::none());
176194
} else {
@@ -195,6 +213,8 @@ class PyFeatureBase : public Feature
195213

196214
void copy_to(Feature& other) const override
197215
{
216+
py::gil_scoped_acquire gil;
217+
198218
py::iterable field_list = fields();
199219
for (py::handle field : field_list) {
200220
std::string field_name = field.cast<std::string>();

python/src/pybindings/feature_source_bindings.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ class PyFeatureSourceBase : public FeatureSource
3131

3232
std::size_t count() const override
3333
{
34+
py::gil_scoped_acquire gil;
3435
return py_count().cast<std::size_t>();
3536
}
3637

3738
bool next() override
3839
{
40+
py::gil_scoped_acquire gil;
3941
if (!m_initialized) {
4042
m_it = py_iter();
4143
m_initialized = true;
@@ -52,13 +54,15 @@ class PyFeatureSourceBase : public FeatureSource
5254

5355
const Feature& feature() const override
5456
{
57+
py::gil_scoped_acquire gil;
5558
return m_feature.cast<const Feature&>();
5659
}
5760

5861
virtual py::object py_iter() = 0;
5962

6063
virtual py::object py_srs_wkt() const
6164
{
65+
py::gil_scoped_acquire gil;
6266
return py::none();
6367
}
6468

python/src/pybindings/processor_bindings.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ bind_processor(py::module& m)
3232
.def("add_operation", &Processor::add_operation)
3333
.def("add_col", &Processor::include_col)
3434
.def("add_geom", &Processor::include_geometry)
35-
.def("process", &Processor::process)
35+
.def("process", [](Processor& self) {
36+
py::gil_scoped_release release;
37+
self.process();
38+
})
3639
.def("set_grid_compat_tol", &Processor::set_grid_compat_tol)
3740
.def("set_max_cells_in_memory", &Processor::set_max_cells_in_memory, py::arg("n"))
3841
.def("set_progress_fn", [](Processor& self, py::function fn) {

python/src/pybindings/raster_source_bindings.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,24 @@ class NumPyRaster : public AbstractRaster<T>
3030
NumPyRaster(py::array_t<T, py::array::c_style | py::array::forcecast> array,
3131
const Grid<bounded_extent>& g)
3232
: AbstractRaster<T>(g)
33-
, m_array(array)
33+
, m_array(std::make_unique<py::array_t<T>>(array))
3434
, m_array_proxy(array.template unchecked<2>())
3535
{
3636
}
3737

38+
virtual ~NumPyRaster()
39+
{
40+
py::gil_scoped_acquire gil;
41+
m_array.reset();
42+
}
43+
3844
T operator()(std::size_t row, std::size_t col) const override
3945
{
4046
return m_array_proxy(row, col);
4147
}
4248

4349
private:
44-
py::array_t<T> m_array;
50+
std::unique_ptr<py::array_t<T>> m_array;
4551
Unchecked2DArrayProxy m_array_proxy;
4652
};
4753

@@ -83,6 +89,8 @@ class PyRasterSourceBase : public RasterSource
8389

8490
RasterVariant read_box(const Box& box) override
8591
{
92+
py::gil_scoped_acquire gil;
93+
8694
auto cropped_grid = grid().crop(box);
8795

8896
auto x0 = cropped_grid.col_offset(grid());
@@ -119,6 +127,8 @@ class PyRasterSourceBase : public RasterSource
119127
const Grid<bounded_extent>& grid() const override
120128
{
121129
if (m_grid == nullptr) {
130+
py::gil_scoped_acquire gil;
131+
122132
py::sequence grid_ext = extent();
123133

124134
if (grid_ext.size() != 4) {

python/src/pybindings/writer_bindings.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class PyWriter : public OutputWriter
4545

4646
void write(const Feature& f) override
4747
{
48+
py::gil_scoped_acquire gil;
49+
4850
// https://github.com/pybind/pybind11/issues/2033#issuecomment-703177186
4951
py::object dummy = py::cast(f, py::return_value_policy::reference);
5052
PYBIND11_OVERLOAD_PURE(void, PyWriter, write, f);

0 commit comments

Comments
 (0)