Add compiler timing diagnostics to mjsCompiler, printed by compile.cc

For example, `compile mujoco_menagerie/robotis_op3/scene.xml` now outputs

```
Compile 1 (cold cache):
  total:      317.2 ms
  assets:     284.8 ms (wall clock)
    load:     616.1 ms
    hull:      26.4 ms
    poly:     137.8 ms
    inert:    177.8 ms
    bvh:      568.2 ms
    octr:       1.6 ms
    tex:       25.3 ms
  other:       32.4 ms

Compile 2 (warm cache):
  total:       79.9 ms
  assets:      54.5 ms (wall clock)
    load:     888.5 ms
    hull:       0.0 ms
    poly:       0.0 ms
    inert:      0.0 ms
    bvh:        0.0 ms
    octr:       0.0 ms
    tex:       21.4 ms
  other:       25.3 ms
```

PiperOrigin-RevId: 917850214
Change-Id: Iaec86230bec0faf2e47820e20cbff61de5b2621e
This commit is contained in:
Yuval Tassa
2026-05-19 08:27:35 -07:00
committed by Copybara-Service
parent f712eed4ce
commit bdf00966f9
23 changed files with 309 additions and 43 deletions
+12
View File
@@ -828,6 +828,18 @@ Type of built-in procedural mesh.
.. mujoco-include:: mjtMeshBuiltin
.. _mjtCTimer:
mjtCTimer
~~~~~~~~~
Compiler timing categories, used in :ref:`mjs_getTimer`. Top-level timers (``TOTAL``, ``ASSETS``) measure wall-clock
time. Asset sub-timers measure CPU time summed across all assets; with multi-threaded compilation their sum can exceed
the ``ASSETS`` wall-clock time.
.. mujoco-include:: mjtCTimer
.. _tyPluginEnums:
Plugins
+9
View File
@@ -2079,6 +2079,15 @@ Write [datetime, type: message] to MUJOCO_LOG.TXT.
Get compiler error message from spec.
.. _mjs_getTimer:
`mjs_getTimer <#mjs_getTimer>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. mujoco-include:: mjs_getTimer
Get compiler timing diagnostics from spec, returns pointer to array of size mjNCTIMER.
.. _mjs_isWarning:
`mjs_isWarning <#mjs_isWarning>`__
+4
View File
@@ -17,6 +17,10 @@ General
release, now uses a fixed seed. The previous implementation seeded with ``mjData.time``, which introduced subtle yet
undesirable time dependence.
- Flexes are now allowed to sleep, with the exception of completely passive (constraint-free) flexes.
- Added compiler timing diagnostics via the new :ref:`mjtCTimer` enum and the :ref:`mjs_getTimer` C API. After
:ref:`mj_compile`, per-category timings (total, assets, mesh loading, convex hull, normals, inertia, BVH, octree,
textures) are available via ``mjs_getTimer(spec)``. The :ref:`compile<saCompile>` sample prints a detailed timing
breakdown when run without an output file.
.. admonition:: Breaking API changes
:class: attention
+17
View File
@@ -1965,6 +1965,22 @@ typedef enum mjtOrientation_ { // type of orientation specifier
mjORIENTATION_ZAXIS, // z axis (minimal rotation)
mjORIENTATION_EULER, // Euler angles
} mjtOrientation;
typedef enum mjtCTimer_ { // compiler timing categories
// top-level timers (wall-clock)
mjCTIMER_TOTAL = 0, // total compile time
mjCTIMER_ASSETS, // asset compilation
// asset sub-timers (CPU time, summed across all assets)
mjCTIMER_TEXTURE, // textures
mjCTIMER_MESH_LOAD, // mesh: file loading
mjCTIMER_MESH_HULL, // mesh: convex hull
mjCTIMER_MESH_POLYGON, // mesh: normals and polygons
mjCTIMER_MESH_INERTIA, // mesh: volume, CoM, inertia
mjCTIMER_MESH_BVH, // mesh: bounding volume hierarchy
mjCTIMER_MESH_OCTREE, // mesh: octree and SDF
mjNCTIMER // number of compiler timers
} mjtCTimer;
typedef struct mjsElement_ { // element type, do not modify
mjtObj elemtype; // element type
uint64_t signature; // compilation signature
@@ -3471,6 +3487,7 @@ void mju_free(void* ptr);
void mj_warning(mjData* d, int warning, int info);
void mju_writeLog(const char* type, const char* msg);
const char* mjs_getError(mjSpec* s);
const double* mjs_getTimer(mjSpec* s);
int mjs_isWarning(mjSpec* s);
void mju_zero3(mjtNum res[3]);
void mju_copy3(mjtNum res[3], const mjtNum data[3]);
+8 -5
View File
@@ -120,16 +120,19 @@ Windows power plan so that the minimum processor state is 100%.
`compile <https://github.com/google-deepmind/mujoco/blob/main/sample/compile.cc>`_
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This code sample evokes the built-in parser and compiler. It implements all possible model conversions from (MJCF, URDF,
MJB) format to (MJCF, MJB, TXT) format. Models saved as MJCF use a canonical subset of our format as described in the
:doc:`../modeling` chapter, and therefore MJCF-to-MJCF conversion will generally result in a different file.
This code sample invokes the built-in parser and compiler. It implements all possible model conversions from (MJCF,
URDF, MJB) format to (MJCF, MJB, TXT) format. Models saved as MJCF use a canonical subset of our format as described in
the :doc:`../modeling` chapter, and therefore MJCF-to-MJCF conversion will generally result in a different file.
The TXT format is a human-readable road-map to the model. It cannot be loaded by MuJoCo, but can be a very useful aid
during model development. It is in one-to-one correspondence with the compiled mjModel. Note also that one can use the
function :ref:`mj_printData` to create a text file which is in one-to-one correspondence
with mjData, although this is not done by the code sample.
If the input file is MJCF and the output file is empty, compilation is performed and timed twice to measure the impact
of the compiler's :ref:`asset cache<Assetcache>`.
If the input file is MJCF or URDF and the output file is empty, compilation is performed twice to measure the impact
of the compiler's :ref:`asset cache<Assetcache>`. A detailed timing breakdown is printed for each compilation, showing
total time, asset processing time (wall clock), and per-category CPU times for meshes and textures. These timings are
read from the :ref:`mjtCTimer` fields via :ref:`mjs_getTimer`, which can be read programmatically
after any call to :ref:`mj_compile`.
.. _saBasic: