-
Notifications
You must be signed in to change notification settings - Fork 826
Just-in-time compiled substep callback #140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| sim.step() # should increment userdata[0] 7 times | ||
| self.assertEqual(sim.data.userdata[0], 7) | ||
|
|
||
| def test_sum_ctrl(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test (test_sum_ctrl) is probably the best standalone example of what it looks like to use this.
mujoco_py/builder.py
Outdated
| if not os.environ.get('MUJOCO_PY_DEBUG_FN_BUILDER', False): | ||
| for f in glob.glob(name + '*'): | ||
| os.remove(f) | ||
| return module.lib.generic_fn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is called "generic" because it's signature matches the mjfGeneric type defined here:
mujoco-py/mujoco_py/pxd/mjdata.pxd
Line 288 in c5f6032
| # typedef void (*mjfGeneric)(const mjModel* m, mjData* d) |
(and also in the mjdata header)
wojzaremba
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Windows version is breaking.
It's fine to disable these tests for windows. Something like that:
@pytest.mark.skipif(sys.platform.startswith("win"), reason="This test fails on windows.")
Finished generating code
FAILED
___________________________ TestSubstep.test_hello ____________________________
self = <mujoco_py.tests.test_substep.TestSubstep testMethod=test_hello>
def test_hello(self):
sim = MjSim(load_model_from_xml(XML.format(nuserdata=0)),
substep_udd_fn=HELLO_FN)
mujoco_py\tests\test_substep.py:42:
mujoco_py\mjsim.pyx:92: in mujoco_py.cymj.MjSim.cinit
self.set_substep_udd_fn(substep_udd_fn)
mujoco_py\mjsim.pyx:210: in mujoco_py.cymj.MjSim.set_substep_udd_fn
substep_udd_fn = build_generic_fn(substep_udd_fn,
mujoco_py\builder.py:337: in build_generic_fn
fixed_library_path = manually_link_libraries(mjpro_path, library_path)
mujoco_py\builder.py:129: in manually_link_libraries
tmp_final_cext_dll_path])
c:\miniconda35-x64\envs\test-environment\lib\subprocess.py:266: in check_call
retcode = call(*popenargs, **kwargs)
c:\miniconda35-x64\envs\test-environment\lib\subprocess.py:247: in call
with Popen(*popenargs, **kwargs) as p:
c:\miniconda35-x64\envs\test-environment\lib\subprocess.py:676: in init
restore_signals, start_new_session)
self = <subprocess.Popen object at 0x000000A3BECF7C50>
args = 'install_name_tool -change @executable_path/libmujoco150.dylib C:\Users\appveyor\.mujoco\mjpro150\bin/libmujoco150.dylib C:\projects\mujoco-py\_generic_fn_vhxddhpmouwlbxy.cp35-win_amd64_final.pyd~'
executable = None, preexec_fn = None, close_fds = True, pass_fds = ()
cwd = None, env = None
startupinfo = <subprocess.STARTUPINFO object at 0x000000A3BECF7588>
creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = -1
c2pwrite = -1, errread = -1, errwrite = -1, unused_restore_signals = True
unused_start_new_session = False
def _execute_child(self, args, executable, preexec_fn, close_fds,
pass_fds, cwd, env,
startupinfo, creationflags, shell,
p2cread, p2cwrite,
c2pread, c2pwrite,
errread, errwrite,
unused_restore_signals, unused_start_new_session):
"""Execute program (MS Windows version)"""
assert not pass_fds, "pass_fds not supported on Windows."
if not isinstance(args, str):
args = list2cmdline(args)
# Process startup details
if startupinfo is None:
startupinfo = STARTUPINFO()
if -1 not in (p2cread, c2pwrite, errwrite):
startupinfo.dwFlags |= _winapi.STARTF_USESTDHANDLES
startupinfo.hStdInput = p2cread
startupinfo.hStdOutput = c2pwrite
startupinfo.hStdError = errwrite
if shell:
startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = _winapi.SW_HIDE
comspec = os.environ.get("COMSPEC", "cmd.exe")
args = '{} /c "{}"'.format (comspec, args)
# Start the process
try:
hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
# no special security
None, None,
int(not close_fds),
creationflags,
env,
cwd,
startupinfo)
E FileNotFoundError: [WinError 2] The system cannot find the file specified
c:\miniconda35-x64\envs\test-environment\lib\subprocess.py:957: FileNotFoundError
mujoco_py/tests/test_substep.py::TestSubstep::test_increment generating ._generic_fn_ucevgvcdpgaisfz.c
mujoco_py/mjsim.pyx
Outdated
| ''' | ||
| if substep_udd_fn is None: | ||
| self._substep_udd_fn = NULL | ||
| elif isinstance(substep_udd_fn, int): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we ensure that "substep_udd_fn" can be only string, or NULL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit safer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason to allow ints is this lets us re-use these functions between sims (in a single python process).
sim1 = MjSim(...., substep_udd_fn=...)
sim2 = MjSim(...., substep_udd_fn=sim1.substep_udd_fn)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added test which shows this
| substep_udd_fn=INCREMENT_FN, | ||
| substep_udd_fields=['foo', 'bar']) | ||
|
|
||
| def test_penetrations(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc: @wojzaremba here's the test you asked for
mujoco_py/mjsim.pyx
Outdated
| next ``udd_state`` after applying the user-defined dynamics. This is | ||
| useful e.g. for reward functions that operate over functions of historical | ||
| state. | ||
| substep_udd_fn : str or int or None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is a substantially different implementation from udd, I would prefer to give it a different name. For example, what about substep_userdata_fn?
f12dbf5 to
b352405
Compare
b352405 to
3763c81
Compare
|
Splitting this into several changes with feedback |
This introduces a couple things together:
Differences between this an our current user-defined-dynamics