Skip to content

Commit d11629b

Browse files
Fixed GIL release issue with Python System and Python TestFixture. Signed-off-by: Amal Dev Haridevan haridevanamaldev@gmail.com
1 parent b1f919b commit d11629b

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

python/src/gz/sim/TestFixture.cc

+11
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,14 @@ defineSimTestFixture(pybind11::object module)
5656
[](TestFixture* self, std::function<void(
5757
const UpdateInfo &, EntityComponentManager &)> _cb)
5858
{
59+
// Add explicit scoped acquire and release of GIL, so that Python Systems
60+
// can be executed
61+
// This acquire and release is only required from the PythonSystem code
62+
// However, adding this here may prevent undefined or unintended behaviors
63+
// in future
64+
pybind11::gil_scoped_acquire gil;
5965
self->OnPreUpdate(_cb);
66+
pybind11::gil_scoped_release gilr;
6067
}
6168
),
6269
pybind11::return_value_policy::reference,
@@ -67,7 +74,9 @@ defineSimTestFixture(pybind11::object module)
6774
[](TestFixture* self, std::function<void(
6875
const UpdateInfo &, EntityComponentManager &)> _cb)
6976
{
77+
pybind11::gil_scoped_acquire gil;
7078
self->OnUpdate(_cb);
79+
pybind11::gil_scoped_release gilr;
7180
}
7281
),
7382
pybind11::return_value_policy::reference,
@@ -78,7 +87,9 @@ defineSimTestFixture(pybind11::object module)
7887
[](TestFixture* self, std::function<void(
7988
const UpdateInfo &, const EntityComponentManager &)> _cb)
8089
{
90+
pybind11::gil_scoped_acquire gil;
8191
self->OnPostUpdate(_cb);
92+
pybind11::gil_scoped_release gilr;
8293
}
8394
),
8495
pybind11::return_value_policy::reference,

python/test/gravity.sdf

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
<mass>1.0</mass>
1818
</inertial>
1919
</link>
20+
<plugin filename="gz-sim-python-system-loader-system"
21+
name="gz::sim::systems::PythonSystemLoader">
22+
<module_name>python_system_TEST</module_name>
23+
</plugin>
2024
</model>
25+
2126
</world>
2227
</sdf>

python/test/python_system_TEST.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env python3
2+
# Copyright (C) 2021 Open Source Robotics Foundation
3+
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
from gz_test_deps.math import Vector3d
17+
from gz_test_deps.sim import Model, Link
18+
import random
19+
20+
21+
class TestSystem(object):
22+
def __init__(self):
23+
self.id = random.randint(1, 100)
24+
25+
def configure(self, entity, sdf, ecm, event_mgr):
26+
self.model = Model(entity)
27+
self.link = Link(self.model.canonical_link(ecm))
28+
print("Configured on", entity)
29+
print("sdf name:", sdf.get_name())
30+
self.force = sdf.get_double("force")
31+
print(f"Applying {self.force} N on link {self.link.name(ecm)}")
32+
33+
def pre_update(self, info, ecm):
34+
if info.paused:
35+
return
36+
37+
if info.iterations % 3000 == 0:
38+
self.link.add_world_force(
39+
ecm, Vector3d(0, 0, self.force),
40+
Vector3d(random.random(), random.random(), 0))
41+
42+
43+
def get_system():
44+
return TestSystem()

src/systems/python_system_loader/PythonSystemLoader.cc

+8
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,21 @@ void PythonSystemLoader::CallPythonMethod(py::object _method, Args &&..._args)
194194
void PythonSystemLoader::PreUpdate(const UpdateInfo &_info,
195195
EntityComponentManager &_ecm)
196196
{
197+
// Add explicit scoped acquire and release of GIL, so that Python
198+
// Systems can be executed.This acquire and release is only required
199+
// from the PythonSystem code
200+
py::gil_scoped_acquire gil;
197201
CallPythonMethod(this->preUpdateMethod, _info, &_ecm);
202+
py::gil_scoped_release gilr;
198203
}
199204

200205
//////////////////////////////////////////////////
201206
void PythonSystemLoader::Update(const UpdateInfo &_info,
202207
EntityComponentManager &_ecm)
203208
{
209+
py::gil_scoped_acquire gil;
204210
CallPythonMethod(this->updateMethod, _info, &_ecm);
211+
py::gil_scoped_release gilr;
205212
}
206213

207214
//////////////////////////////////////////////////
@@ -210,6 +217,7 @@ void PythonSystemLoader::PostUpdate(const UpdateInfo &_info,
210217
{
211218
py::gil_scoped_acquire gil;
212219
CallPythonMethod(this->postUpdateMethod, _info, &_ecm);
220+
py::gil_scoped_release gilr;
213221
}
214222
//////////////////////////////////////////////////
215223
void PythonSystemLoader::Reset(const UpdateInfo &_info,

0 commit comments

Comments
 (0)