Skip to content

Commit

Permalink
Fixed GIL release issue with Python System and Python TestFixture. Si…
Browse files Browse the repository at this point in the history
…gned-off-by: Amal Dev Haridevan [email protected]

Signed-off-by: sdcnlab <[email protected]>
Signed-off-by: Amal Dev Haridevan <[email protected]>
  • Loading branch information
AmalDevHaridevan committed Sep 11, 2024
1 parent b1f919b commit 29598fd
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
11 changes: 11 additions & 0 deletions python/src/gz/sim/TestFixture.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,14 @@ defineSimTestFixture(pybind11::object module)
[](TestFixture* self, std::function<void(
const UpdateInfo &, EntityComponentManager &)> _cb)
{
// Add explicit scoped acquire and release of GIL, so that Python Systems
// can be executed
// This acquire and release is only required from the PythonSystem code
// However, adding this here may prevent undefined or unintended behaviors
// in future
pybind11::gil_scoped_acquire gil;
self->OnPreUpdate(_cb);
pybind11::gil_scoped_release gilr;
}
),
pybind11::return_value_policy::reference,
Expand All @@ -67,7 +74,9 @@ defineSimTestFixture(pybind11::object module)
[](TestFixture* self, std::function<void(
const UpdateInfo &, EntityComponentManager &)> _cb)
{
pybind11::gil_scoped_acquire gil;
self->OnUpdate(_cb);
pybind11::gil_scoped_release gilr;
}
),
pybind11::return_value_policy::reference,
Expand All @@ -78,7 +87,9 @@ defineSimTestFixture(pybind11::object module)
[](TestFixture* self, std::function<void(
const UpdateInfo &, const EntityComponentManager &)> _cb)
{
pybind11::gil_scoped_acquire gil;
self->OnPostUpdate(_cb);
pybind11::gil_scoped_release gilr;
}
),
pybind11::return_value_policy::reference,
Expand Down
5 changes: 5 additions & 0 deletions python/test/gravity.sdf
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
<mass>1.0</mass>
</inertial>
</link>
<plugin filename="gz-sim-python-system-loader-system"
name="gz::sim::systems::PythonSystemLoader">
<module_name>python_system_TEST</module_name>
</plugin>
</model>

</world>
</sdf>
44 changes: 44 additions & 0 deletions python/test/python_system_TEST.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env python3
# Copyright (C) 2021 Open Source Robotics Foundation

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from gz_test_deps.math import Vector3d
from gz_test_deps.sim import Model, Link
import random


class TestSystem(object):
def __init__(self):
self.id = random.randint(1, 100)

def configure(self, entity, sdf, ecm, event_mgr):
self.model = Model(entity)
self.link = Link(self.model.canonical_link(ecm))
print("Configured on", entity)
print("sdf name:", sdf.get_name())
self.force = sdf.get_double("force")
print(f"Applying {self.force} N on link {self.link.name(ecm)}")

def pre_update(self, info, ecm):
if info.paused:
return

if info.iterations % 3000 == 0:
self.link.add_world_force(
ecm, Vector3d(0, 0, self.force),
Vector3d(random.random(), random.random(), 0))


def get_system():
return TestSystem()
8 changes: 8 additions & 0 deletions src/systems/python_system_loader/PythonSystemLoader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,21 @@ void PythonSystemLoader::CallPythonMethod(py::object _method, Args &&..._args)
void PythonSystemLoader::PreUpdate(const UpdateInfo &_info,
EntityComponentManager &_ecm)
{
// Add explicit scoped acquire and release of GIL, so that Python
// Systems can be executed.This acquire and release is only required
// from the PythonSystem code
py::gil_scoped_acquire gil;
CallPythonMethod(this->preUpdateMethod, _info, &_ecm);
py::gil_scoped_release gilr;
}

//////////////////////////////////////////////////
void PythonSystemLoader::Update(const UpdateInfo &_info,
EntityComponentManager &_ecm)
{
py::gil_scoped_acquire gil;
CallPythonMethod(this->updateMethod, _info, &_ecm);
py::gil_scoped_release gilr;
}

//////////////////////////////////////////////////
Expand All @@ -210,6 +217,7 @@ void PythonSystemLoader::PostUpdate(const UpdateInfo &_info,
{
py::gil_scoped_acquire gil;
CallPythonMethod(this->postUpdateMethod, _info, &_ecm);
py::gil_scoped_release gilr;
}
//////////////////////////////////////////////////
void PythonSystemLoader::Reset(const UpdateInfo &_info,
Expand Down

0 comments on commit 29598fd

Please sign in to comment.