From c0357ef3d06f8ab8a7654802982a31c982015df2 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Fri, 13 Oct 2023 16:31:41 -0700 Subject: [PATCH] Improve documentation related to engine-internal threading. PiperOrigin-RevId: 573346658 Change-Id: I112eba10b8f71b3a0aa27fa162a4a589be7ec3a7 --- doc/APIreference/APItypes.rst | 2 + doc/changelog.rst | 43 ++++++++++----------- doc/programming/samples.rst | 71 +++++++++++++++++++++++++++++------ sample/testspeed.cc | 2 +- 4 files changed, 84 insertions(+), 34 deletions(-) diff --git a/doc/APIreference/APItypes.rst b/doc/APIreference/APItypes.rst index a8450195..d2a812d6 100644 --- a/doc/APIreference/APItypes.rst +++ b/doc/APIreference/APItypes.rst @@ -502,6 +502,8 @@ These are the possible framebuffers. They are used as an argument to the functio .. mujoco-include:: mjtFramebuffer +.. _mjtDepthMap: + mjtDepthMap ~~~~~~~~~~~ diff --git a/doc/changelog.rst b/doc/changelog.rst index f9ebdcfa..86e4504f 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -29,13 +29,16 @@ New features gradient at query points. See the :ref:`documentation` for more details. 3. Added :ref:`mjThreadPool` and :ref:`mjTask` which allow for multi-threaded operations within the MuJoCo engine - pipeline. + pipeline. If engine-internal threading is enabled, the following operations will be multi-threaded: - If engine-level threading is enabled, the following operations will be multi-threaded: - - - Island constraint resolution, if island discovery is :ref:`enable flag` and the :ref:`CG` is selected. + - Island constraint resolution, if island discovery is :ref:`enabled` and the + :ref:`CG solver` is selected. The + `22 humanoids `__ model shows a 3x + speedup compared to the single threaded simulation. - Inertia-related computations and collision detection will happen in parallel. + Engine-internal threading is a work in progress and currently only available in first-party code via the + :ref:`testspeed` utility, exposed with the ``npoolthread`` flag. .. youtube:: ra2bTiZHGlw :align: right @@ -108,7 +111,7 @@ General 14. Added a new :ref:`dyntype`, ``filterexact``, which updates first-order filter states with the exact formula rather than with Euler integration. 15. Added an actuator attribute, :ref:`actearly`, which uses semi-implicit integration for - actuator forces: using the next step's actuator state to compute the current actuator forces at the current timestep. + actuator forces: using the next step's actuator state to compute the current actuator forces. 16. Renamed ``actuatorforcerange`` and ``actuatorforcelimited``, introduced in the previous version to :ref:`actuatorfrcrange` and :ref:`actuatorfrclimited`, respectively. @@ -132,24 +135,22 @@ General attributes are specified. See the following `example model `__. - Note that these attributes only take effect for offline rendering and do not affect interactive visualisation. -23. Added multi-threaded constraint solving via :ref:`mj_island` and :ref:`mjThreadPool` to :ref:`testspeed` - exposed via npoolthread flag. The `22 humanoids `__ - model shows a 3x speedup compared to the single threaded simulation. -24. Implemented reversed Z rendering for better depth precision. An enum :ref:`mjtDepthMap` was added with values - :ref:`mjDEPTH_ZERONEAR` and :ref:`mjDEPTH_ZEROFAR`, which can be used to set the new ``readDepthMap`` attribute in - :ref:`mjrContext`` to control how the depth returned by :ref:`mjr_readPixels` is mapped from ``znear`` to ``zfar``. - `Contribution `__ by `Levi Burner `__. -25. Deleted the code sample ``testxml``. The functionality provided by this utility is implemented in the - `WriteReadCompare __ test. +23. Implemented reversed Z rendering for better depth precision. An enum :ref:`mjtDepthMap` was added with values + ``mjDEPTH_ZERONEAR`` and ``mjDEPTH_ZEROFAR``, which can be used to set the new ``readDepthMap`` attribute in + :ref:`mjrContext` to control how the depth returned by :ref:`mjr_readPixels` is mapped from ``znear`` to ``zfar``. + `Contribution `__ by + `Levi Burner `__. +24. Deleted the code sample ``testxml``. The functionality provided by this utility is implemented in the + `WriteReadCompare `__ test. Python bindings ^^^^^^^^^^^^^^^ -26. Fixed `#870 `__ where calling ``update_scene`` with an invalid +25. Fixed `#870 `__ where calling ``update_scene`` with an invalid camera name used the default camera. -27. Added ``user_scn`` to the :ref:`passive viewer` handle, which allows users to add custom +26. Added ``user_scn`` to the :ref:`passive viewer` handle, which allows users to add custom visualization geoms (`#1023 `__). -28. Added optional boolean keyword arguments ``show_left_ui`` and ``show_right_ui`` to the functions ``viewer.launch`` +27. Added optional boolean keyword arguments ``show_left_ui`` and ``show_right_ui`` to the functions ``viewer.launch`` and ``viewer.launch_passive``, which allow users to launch a viewer with UI panels hidden. Simulate @@ -159,21 +160,21 @@ Simulate :align: right :width: 240px -29. Added **state history** mechanism to :ref:`simulate` and the managed +28. Added **state history** mechanism to :ref:`simulate` and the managed :ref:`Python viewer`. State history can be viewed by scrubbing the History slider and (more precisely) with the left and right arrow keys. See screen capture: -30. The ``LOADING...`` label is now shown correctly. +29. The ``LOADING...`` label is now shown correctly. `Contribution `__ by `Levi Burner `__. Bug fixes ^^^^^^^^^ -31. Fixed a bug that was causing :ref:`geom margin` to be ignored during the construction of +30. Fixed a bug that was causing :ref:`geom margin` to be ignored during the construction of midphase collision trees. -32. Fixed a bug that was generating incorrect values in ``efc_diagApprox`` for weld equality constraints. +31. Fixed a bug that was generating incorrect values in ``efc_diagApprox`` for weld equality constraints. Version 2.3.7 (July 20, 2023) diff --git a/doc/programming/samples.rst b/doc/programming/samples.rst index fdf3ac99..b482ba56 100644 --- a/doc/programming/samples.rst +++ b/doc/programming/samples.rst @@ -12,19 +12,66 @@ with the library. `testspeed `_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This code sample tests the simulation speed for a given model. The command line arguments are the model file, the -number of time steps to simulate, the number of parallel threads to use, and a flag to enable internal profiling (the -last two are optional). When N threads are specified with N>1, the code allocates a single mjModel and per-thread -mjData, and runs N identical simulations in parallel. The idea is to test performance with all cores active, similar -to Reinforcement Learning scenarios where samples are collected in parallel. The optimal N usually equals the number -of logical cores. By default the simulation starts from the model reference configuration qpos0 and qvel=0. However if -a keyframe named "test" is present in the model, it is used as the initial state state. +This code sample times the simulation of a given model. The timing is straightforward: the simulation of the passive +dynamics (with optional control noise) is rolled-out for the specified number of steps, while collecting statistics +about the number of contacts, scalar constraints, and CPU times from internal profiling. The results are then printed to +the console. To simulate controlled dynamics instead of passive dynamics one can either install a control callback +:ref:`mjcb_control`, or modify the code to set control signals explicitly, as explained in the :ref:`simulation loop +` section below. This command-line utility is run with -The timing code is straightforward: the simulation of the passive dynamics is advanced for the specified number of -steps, while collecting statistics about the number of contacts, scalar constraints, and CPU times from internal -profiling. The results are then printed in the console. To simulate controlled dynamics instead of passive dynamics -one can either install the control callback :ref:`mjcb_control`, or set control signals -explicitly as explained in the :ref:`simulation loop ` section below. +.. code-block:: Shell + + testspeed modelfile [nstep nthread ctrlnoise npoolthread] + +Where the command line arguments are + +.. list-table:: + :width: 95% + :align: left + :widths: 1 1 5 + :header-rows: 1 + + * - Argument + - Default + - Meaning + * - ``modelfile`` + - (required) + - path to model + * - ``nstep`` + - 10000 + - number of steps per rollout + * - ``nthread`` + - 1 + - number of threads running parallel rollouts + * - ``ctrlnoise`` + - 0.01 + - scale of pseudo-random noise injected into actuators + * - ``npoolthread`` + - 1 + - number of threads in engine-internal threadpool + +**Notes:** + +- When ``nthread > 1`` is specified, the code allocates a single mjModel and per-thread mjData, and runs ``nthread`` + identical simulations in parallel. This tests performance with all cores active, as in Reinforcement + Learning scenarios where samples are collected in parallel. The optimal ``nthread`` usually equals the number of + logical cores. +- By default, the simulation starts from the model reference configuration with zero velocities. However, if a + keyframe named "test" is present in the model, it is used as the initial state. +- The ``ctrlnoise`` argument prevents models from settling into a static state where, due to warmstarts, one can + measure artificially faster simulation. +- When ``npoolthread > 1`` is specified, an engine-internal :ref:`mjThreadPool` is created with the specified number of + threads, to speed up simulation of large scenes. Note that while it is possible to to use both ``nthread`` and + ``npoolthread``, the scenarios for which one would want these different type of multithreading are usually mutually + exclusive. +- For more repeatable performance statistics, run the tool with the ``performance`` + `governor `__ on Linux, or the + ``High Performance`` power plan on Windows, to reduce noise from CPU scaling. +- Many modern CPUs contain a mixture of "performance" and "efficiency" cores. Users should consider restricting the + process to only run on the same type of cores for more interpretable performance statistics. This can be done via the + `taskset `__ command on Linux, or the + `start /affinity `__ + command on Windows (processor affinity cannot be specified through documented API means on macOS). .. _saCompile: diff --git a/sample/testspeed.cc b/sample/testspeed.cc index c64b8698..5ac51a80 100644 --- a/sample/testspeed.cc +++ b/sample/testspeed.cc @@ -116,7 +116,7 @@ int main(int argc, char** argv) { " -------- ------- --------\n" " modelfile path to model (required)\n" " nstep 10000 number of steps per rollout\n" - " nthread 1 number of threads for which to run parallel rollouts\n" + " nthread 1 number of threads running parallel rollouts\n" " ctrlnoise 0.01 scale of pseudo-random noise injected into actuators\n" " npoolthread 0 number of threads in engine-internal threadpool\n" "\n"