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
+17
View File
@@ -718,6 +718,23 @@ ENUMS: Mapping[str, EnumDecl] = dict([
('mjORIENTATION_EULER', 4),
]),
)),
('mjtCTimer',
EnumDecl(
name='mjtCTimer',
declname='enum mjtCTimer_',
values=dict([
('mjCTIMER_TOTAL', 0),
('mjCTIMER_ASSETS', 1),
('mjCTIMER_TEXTURE', 2),
('mjCTIMER_MESH_LOAD', 3),
('mjCTIMER_MESH_HULL', 4),
('mjCTIMER_MESH_POLYGON', 5),
('mjCTIMER_MESH_INERTIA', 6),
('mjCTIMER_MESH_BVH', 7),
('mjCTIMER_MESH_OCTREE', 8),
('mjNCTIMER', 9),
]),
)),
('mjtCatBit',
EnumDecl(
name='mjtCatBit',
+16
View File
@@ -6471,6 +6471,22 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
),
doc='Get compiler error message from spec.',
)),
('mjs_getTimer',
FunctionDecl(
name='mjs_getTimer',
return_type=PointerType(
inner_type=ValueType(name='double', is_const=True),
),
parameters=(
FunctionParameterDecl(
name='s',
type=PointerType(
inner_type=ValueType(name='mjSpec'),
),
),
),
doc='Get compiler timing diagnostics from spec, returns pointer to array of size mjNCTIMER.', # pylint: disable=line-too-long
)),
('mjs_isWarning',
FunctionDecl(
name='mjs_isWarning',
+8
View File
@@ -55,6 +55,7 @@ using MjDouble3 = Eigen::Map<Eigen::Vector3d>;
using MjDouble4 = Eigen::Map<Eigen::Vector4d>;
using MjDouble5 = Eigen::Map<Eigen::Matrix<double, 5, 1>>;
using MjDouble6 = Eigen::Map<Eigen::Matrix<double, 6, 1>>;
using MjDouble9 = Eigen::Map<Eigen::Matrix<double, 9, 1>>;
using MjDouble10 = Eigen::Map<Eigen::Matrix<double, 10, 1>>;
using MjDouble11 = Eigen::Map<Eigen::Matrix<double, 11, 1>>;
using MjDoubleVec = Eigen::Map<Eigen::VectorXd>;
@@ -69,6 +70,7 @@ using MjDoubleRef3 = Eigen::Ref<const Eigen::Vector3d>;
using MjDoubleRef4 = Eigen::Ref<const Eigen::Vector4d>;
using MjDoubleRef5 = Eigen::Ref<const Eigen::Matrix<double, 5, 1>>;
using MjDoubleRef6 = Eigen::Ref<const Eigen::Matrix<double, 6, 1>>;
using MjDoubleRef9 = Eigen::Ref<const Eigen::Matrix<double, 9, 1>>;
using MjDoubleRef10 = Eigen::Ref<const Eigen::Matrix<double, 10, 1>>;
using MjDoubleRef11 = Eigen::Ref<const Eigen::Matrix<double, 11, 1>>;
using MjDoubleRefVec = Eigen::Ref<const Eigen::VectorXd>;
@@ -461,6 +463,12 @@ PYBIND11_MODULE(_specs, m) {
mjSpec.def_property_readonly("_address", [](const MjSpec& self) {
return reinterpret_cast<uintptr_t>(self.ptr);
});
mjSpec.def_property_readonly(
"timer",
[](MjSpec& self) -> MjDouble9 {
return MjDouble9(const_cast<double*>(mjs_getTimer(self.ptr)));
},
py::return_value_policy::reference_internal);
mjSpec.def_property(
"copy_during_attach",
[](MjSpec& self) {
+18
View File
@@ -47,6 +47,24 @@ class SpecsTest(absltest.TestCase):
self.assertIsInstance(spec.worldbody, mujoco.MjsBody)
self.assertIsInstance(spec.worldbody, typing.get_args(mujoco.MjStruct))
def test_timer(self):
xml = """
<mujoco>
<asset>
<texture name="grid" type="2d" builtin="checker" width="300" height="300" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
<material name="grid" texture="grid"/>
</asset>
<worldbody>
<geom type="plane" size="1 1 1" material="grid"/>
</worldbody>
</mujoco>
"""
spec = mujoco.MjSpec.from_string(xml)
model = spec.compile()
self.assertGreater(spec.timer[mujoco.mjtCTimer.mjCTIMER_TOTAL], 0)
self.assertGreater(spec.timer[mujoco.mjtCTimer.mjCTIMER_ASSETS], 0)
self.assertGreater(spec.timer[mujoco.mjtCTimer.mjCTIMER_TEXTURE], 0)
def test_basic(self):
# Create a spec.
spec = mujoco.MjSpec()