Skip to content

Commit

Permalink
Bug fix for multithreaded rendering. (openai#85)
Browse files Browse the repository at this point in the history
* Bug fix.

* Improvements suggested by PW.
  • Loading branch information
wojzaremba committed Aug 3, 2017
1 parent aa82c0e commit 56929b9
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
24 changes: 14 additions & 10 deletions mujoco_py/mjsim.pyx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from xml.dom import minidom
from mujoco_py.utils import remove_empty_lines
from threading import Lock

_MjSim_render_lock = Lock()


cdef class MjSim(object):
Expand Down Expand Up @@ -122,16 +125,17 @@ cdef class MjSim(object):
camera_id = self.model.camera_name2id(camera_name)

if mode == 'offscreen':
if self._render_context_offscreen is None:
render_context = MjRenderContextOffscreen(
self, device_id=device_id)
else:
render_context = self._render_context_offscreen

render_context.render(
width=width, height=height, camera_id=camera_id)
return render_context.read_pixels(
width, height, depth=depth)
with _MjSim_render_lock:
if self._render_context_offscreen is None:
render_context = MjRenderContextOffscreen(
self, device_id=device_id)
else:
render_context = self._render_context_offscreen

render_context.render(
width=width, height=height, camera_id=camera_id)
return render_context.read_pixels(
width, height, depth=depth)
elif mode == 'window':
if self._render_context_window is None:
from mujoco_py.mjviewer import MjViewer
Expand Down
33 changes: 30 additions & 3 deletions mujoco_py/tests/test_cymj.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
from mujoco_py import const, cymj
from mujoco_py.tests.utils import compare_imgs, requires_rendering
import scipy.misc
import os
import shutil
import glob
from threading import Thread, Event
from multiprocessing import get_context
import sys

Expand All @@ -22,6 +20,7 @@
<worldbody>
<light name="light1" diffuse=".5 .5 .5" pos="0 0 3" dir="0 0 -1"/>
<camera name="camera1" pos="3 0 0" zaxis="1 0 0" />
<camera name="camera2" pos="4 0 0" zaxis="1 0 0" />
<geom name="geom1" pos="0.5 0.4 0.3" type="plane" size="1 1 0.1" rgba=".9 0 0 1"/>
<body pos="0 0 1" name="body1">
<joint name="joint1" type="free"/>
Expand Down Expand Up @@ -650,6 +649,34 @@ def test_sensors():
sim.data.get_sensor("touchsensor")


@requires_rendering
def test_concurrent_rendering():
'''Best-effort testing that concurrent multi-threaded rendering works.
The test has no guarantees around being deterministic, but if it fails
you know something is wrong with concurrent rendering. If it passes,
things are probably working.'''
def func(sim, event):
event.wait()
sim.data.qpos[:] = 0.0
sim.forward()
img1 = sim.render(width=40, height=40, camera_name="camera1")
assert np.sum(img1[:]) == 23255
img2 = sim.render(width=40, height=40, camera_name="camera2")
assert np.sum(img2[:]) == 12007

model = load_model_from_xml(BASIC_MODEL_XML)
sim = MjSim(model)
sim.render(100, 100)
event = Event()
threads = []
for _ in range(100):
thread = Thread(target=func, args=(sim, event))
threads.append(thread)
thread.start()
event.set()
for thread in threads:
thread.join()

@requires_rendering
def test_high_res():
model = load_model_from_xml(BASIC_MODEL_XML)
Expand Down
2 changes: 1 addition & 1 deletion mujoco_py/version.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__all__ = ['__version__', 'get_version']

version_info = (1, 50, 1, 12)
version_info = (1, 50, 1, 14)
# format:
# ('mujoco_major', 'mujoco_minor', 'mujoco_py_major', 'mujoco_py_minor')

Expand Down

0 comments on commit 56929b9

Please sign in to comment.