In pyzed, other Python threads in the same process stop running while grab() or reset_positional_tracking() is running. It looks like the wrapper doesn’t release the GIL during these calls.
Setup: ZED X Mini, SVGA @ 60 fps, GEN_3 tracking with area memory, ZED SDK [version], Python 3.10, Jetson AGX Orin, JetPack [version].
What I see:
An IMU thread polling get_sensors_data(CURRENT) at 200 Hz only publishes at the camera’s 60 Hz.
During reset_positional_tracking() (2.8 s), it publishes nothing.
A plain heartbeat thread that only calls time.sleep(0.005) and never touches the camera also stalls for 2768 ms during the reset.
Repro:
python
import threading, time
import pyzed.sl as sl
zed = sl.Camera()
init = sl.InitParameters()
init.camera_resolution = sl.RESOLUTION.SVGA
init.camera_fps = 60
assert zed.open(init) == sl.ERROR_CODE.SUCCESS
tp = sl.PositionalTrackingParameters()
tp.enable_area_memory = True
zed.enable_positional_tracking(tp)
def heartbeat():
last = time.monotonic()
while True:
time.sleep(0.005)
now = time.monotonic()
if now - last > 0.05:
print(f"heartbeat stalled {1e3 * (now - last):.0f} ms")
last = now
threading.Thread(target=heartbeat, daemon=True).start()
rt = sl.RuntimeParameters()
for i in range(300):
zed.grab(rt)
if i == 150:
zed.reset_positional_tracking(sl.Transform())
zed.close()
Question: Does pyzed hold the GIL during these calls on purpose? Would it be safe to release it (with nogil:) so other threads, such as an IMU reader, keep running?
thank you for the detailed report and the reproducer.
This is only partially correct. I checked the source code of the ZED Python API:
Camera.grab() releases the GIL (with nogil:) since ZED SDK v5.0.
Camera.get_sensors_data() releases the GIL since ZED SDK v5.1.
Camera.reset_positional_tracking() does not release the GIL in any version, including the latest v5.4.0.
During reset_positional_tracking() (2.8 s), it publishes nothing.
A plain heartbeat thread that only calls time.sleep(0.005) and never touches the camera also stalls for 2768 ms during the reset.
This is caused by the missing GIL release in reset_positional_tracking(). I’m going to report it to the StereoLabs development team so it can be fixed in a future release.
In the meantime, you can patch the wrapper locally since it’s open source. Clone the repository for your ZED SDK version and apply these two changes.