From 4830f5a79ef88cc1c3187ee3f382a78ab8f32d25 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Tue, 6 Jan 2026 11:06:28 -0800 Subject: [PATCH] Add missing documentation for the asset cache. Also improve `compile` sample timing logic and documentation. PiperOrigin-RevId: 852855741 Change-Id: I9b2798208198ca68cf4cee9c968772954ada91c5 --- doc/APIreference/APIfunctions.rst | 1 + doc/APIreference/functions.rst | 59 ++++++++++++++++++++++--- doc/APIreference/functions_override.rst | 3 +- doc/programming/samples.rst | 3 ++ sample/compile.cc | 27 ++++++----- 5 files changed, 73 insertions(+), 20 deletions(-) diff --git a/doc/APIreference/APIfunctions.rst b/doc/APIreference/APIfunctions.rst index e8701868..0a20ca2f 100644 --- a/doc/APIreference/APIfunctions.rst +++ b/doc/APIreference/APIfunctions.rst @@ -28,6 +28,7 @@ API function can be classified as: - :ref:`Ray casting`. - :ref:`Printing` of various quantities. - :ref:`Virtual file system`, used to load assets from memory. + - :ref:`Asset cache`, used to speed up model compilation. - :ref:`Initialization` of data structures. - :ref:`Error and memory`. - :ref:`Miscellaneous` functions. diff --git a/doc/APIreference/functions.rst b/doc/APIreference/functions.rst index d070db48..2923c26a 100644 --- a/doc/APIreference/functions.rst +++ b/doc/APIreference/functions.rst @@ -1359,12 +1359,6 @@ Add file to VFS. The directory argument is optional and can be NULL or empty. Re *Nullable:* ``directory`` - -.. Assetcache: - -The asset cache is a mechanism for caching assets (e.g. textures, meshes, etc.) to avoid repeated slow recompilation. -The following methods provide way to control the capacity of the cache or to disable it altogether. - .. _mj_addBufferVFS: `mj_addBufferVFS <#mj_addBufferVFS>`__ @@ -1392,6 +1386,59 @@ Delete file from VFS, return 0: success, -1: not found in VFS. Delete all files from VFS and deallocates VFS internal memory. +.. _Assetcache: + +Asset cache +^^^^^^^^^^^ + +The asset cache is a mechanism for caching assets (e.g. textures, meshes, etc.) to avoid repeated slow recompilation. +The following methods provide way to control the capacity of the cache or to disable it altogether. + +.. _mj_getCacheSize: + +`mj_getCacheSize <#mj_getCacheSize>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mj_getCacheSize + +Get the current size of the asset cache in bytes. + +.. _mj_getCacheCapacity: + +`mj_getCacheCapacity <#mj_getCacheCapacity>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mj_getCacheCapacity + +Get the capacity of the asset cache in bytes. + +.. _mj_setCacheCapacity: + +`mj_setCacheCapacity <#mj_setCacheCapacity>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mj_setCacheCapacity + +Set the capacity of the asset cache in bytes (0 to disable); returns the new capacity. + +.. _mj_getCache: + +`mj_getCache <#mj_getCache>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mj_getCache + +Get the internal asset cache used by the compiler. + +.. _mj_clearCache: + +`mj_clearCache <#mj_clearCache>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mj_clearCache + +Clear the asset cache. + .. _Initialization: Initialization diff --git a/doc/APIreference/functions_override.rst b/doc/APIreference/functions_override.rst index a8d7e181..a464c585 100644 --- a/doc/APIreference/functions_override.rst +++ b/doc/APIreference/functions_override.rst @@ -25,8 +25,7 @@ Add file to VFS. The directory argument is optional and can be NULL or empty. Re *Nullable:* ``directory`` - -.. Assetcache: +.. _Assetcache: The asset cache is a mechanism for caching assets (e.g. textures, meshes, etc.) to avoid repeated slow recompilation. The following methods provide way to control the capacity of the cache or to disable it altogether. diff --git a/doc/programming/samples.rst b/doc/programming/samples.rst index 9e105ce0..1271de19 100644 --- a/doc/programming/samples.rst +++ b/doc/programming/samples.rst @@ -128,6 +128,9 @@ during model development. It is in one-to-one correspondence with the compiled m 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`. + .. _saBasic: `basic `_ diff --git a/sample/compile.cc b/sample/compile.cc index c562d43c..97974dd3 100644 --- a/sample/compile.cc +++ b/sample/compile.cc @@ -22,22 +22,26 @@ #include + // help static constexpr char helpstring[] = "\n Usage: compile infile outfile\n" " infile can be in mjcf, urdf, mjb format\n" " outfile can be in mjcf, mjb, txt format, or empty\n\n" - " if infile is mjcf, compilation will be timed twice to measure the impact of caching\n\n" + " if infile is mjcf and outfile is empty, compilation will be " + "timed twice to measure the impact of caching\n\n" " Example: compile model.xml [model.mjb]\n"; + // timer (seconds) -mjtNum gettm(void) { +double gettm(void) { using Clock = std::chrono::steady_clock; - using Seconds = std::chrono::duration; + using Seconds = std::chrono::duration; static const Clock::time_point tm_start = Clock::now(); return Seconds(Clock::now() - tm_start).count(); } + // deallocate and print message int finish(const char* msg = 0, int exitcode = EXIT_SUCCESS, mjModel* m = 0) { // deallocated everything @@ -99,7 +103,6 @@ int filetype(const char* filename) { } - // main function int main(int argc, char** argv) { @@ -117,8 +120,8 @@ int main(int argc, char** argv) { int type2 = argc==2 ? typeNONE : filetype(argv[2]); // check types - if (type1==typeUNKNOWN || type1==typeTXT || - type2==typeUNKNOWN || (type1==typeMJB && type2==typeXML)) { + if (type1 == typeUNKNOWN || type1 == typeTXT || + type2 == typeUNKNOWN || (type1 == typeMJB && type2 == typeXML)) { return finish("Illegal combination of file formats", EXIT_FAILURE); } @@ -140,7 +143,7 @@ int main(int argc, char** argv) { double starttime = gettm(); m = mj_loadXML(argv[1], 0, error, 1000); first = gettm() - starttime; - if (m) { + if (m && type2 == typeNONE) { mj_deleteModel(m); starttime = gettm(); m = mj_loadXML(argv[1], 0, error, 1000); @@ -152,7 +155,7 @@ int main(int argc, char** argv) { // check error if (!m) { - if (type1==typeXML) { + if (type1 == typeXML) { return finish(error, EXIT_FAILURE); } else { return finish("Could not load model", EXIT_FAILURE); @@ -160,19 +163,19 @@ int main(int argc, char** argv) { } // save model - if (type2==typeXML) { + if (type2 == typeXML) { if (!mj_saveLastXML(argv[2], m, error, 1000)) { return finish(error, EXIT_FAILURE, m); } - } else if (type2==typeMJB) { + } else if (type2 == typeMJB) { mj_saveModel(m, argv[2], 0, 0); - } else if (type2==typeTXT) { + } else if (type2 == typeTXT) { mj_printModel(m, argv[2]); } // finalize char msg[1000]; - if (first) { + if (first && type2 == typeNONE) { snprintf(msg, sizeof(msg), "Done.\n" "First compile: %.4gs\n" "Second compile: %.4gs",